SiriDB Admin Tool can be used to talk with the new API and provides both a
command-line and a graphical web interface. Pre-compiled versions for
different platforms can be found and downloaded from:
- https://github.com/transceptor-technology/siridb-admin/releases/latest
+ https://github.com/transceptor-technology/siridb-service/releases/latest
* Added version check before creating a new pool or replica. (issue #62)
siridb-server (2.0.13) xenial; urgency=medium
- * Fixed wrapping imap to slist functions with appropriate locks.
+ * Fixed wrapping imap to vec functions with appropriate locks.
(see issue #51)
-- Jeroen van der Heijden <jeroen@transceptor.technology> Fri, 17 Feb 2017 13:46:53 +0000
-include src/xpath/subdir.mk
-include src/xmath/subdir.mk
-include src/timeit/subdir.mk
--include src/strextra/subdir.mk
--include src/slist/subdir.mk
--include src/siri/admin/subdir.mk
+-include src/xstr/subdir.mk
+-include src/vec/subdir.mk
+-include src/siri/service/subdir.mk
-include src/siri/parser/subdir.mk
-include src/siri/net/subdir.mk
-include src/siri/help/subdir.mk
src/owcrypt \
src/procinfo \
src/qpack \
-src/siri/admin \
+src/siri/service \
src/siri/args \
src/siri \
src/siri/cfg \
src/siri/grammar \
src/siri/help \
src/siri/net \
-src/slist \
-src/strextra \
+src/vec \
+src/xstr \
src/timeit \
src/xmath \
src/xpath \
+++ /dev/null
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
-# Add inputs and outputs from these tool invocations to the build variables
-C_SRCS += \
-../src/siri/admin/account.c \
-../src/siri/admin/client.c \
-../src/siri/admin/request.c
-
-OBJS += \
-./src/siri/admin/account.o \
-./src/siri/admin/client.o \
-./src/siri/admin/request.o
-
-C_DEPS += \
-./src/siri/admin/account.d \
-./src/siri/admin/client.d \
-./src/siri/admin/request.d
-
-
-# Each subdirectory must supply rules for building sources it contributes
-src/siri/admin/%.o: ../src/siri/admin/%.c
- @echo 'Building file: $<'
- @echo 'Invoking: GCC C Compiler'
- gcc -I../include -O0 -g3 -Wall -Wextra $(CPPFLAGS) $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
- @echo 'Finished building: $<'
- @echo ' '
-
-
--- /dev/null
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+C_SRCS += \
+../src/siri/service/account.c \
+../src/siri/service/client.c \
+../src/siri/service/request.c
+
+OBJS += \
+./src/siri/service/account.o \
+./src/siri/service/client.o \
+./src/siri/service/request.o
+
+C_DEPS += \
+./src/siri/service/account.d \
+./src/siri/service/client.d \
+./src/siri/service/request.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+src/siri/service/%.o: ../src/siri/service/%.c
+ @echo 'Building file: $<'
+ @echo 'Invoking: GCC C Compiler'
+ gcc -I../include -O0 -g3 -Wall -Wextra $(CPPFLAGS) $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
+ @echo 'Finished building: $<'
+ @echo ' '
+
+
+++ /dev/null
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
-# Add inputs and outputs from these tool invocations to the build variables
-C_SRCS += \
-../src/slist/slist.c
-
-OBJS += \
-./src/slist/slist.o
-
-C_DEPS += \
-./src/slist/slist.d
-
-
-# Each subdirectory must supply rules for building sources it contributes
-src/slist/%.o: ../src/slist/%.c
- @echo 'Building file: $<'
- @echo 'Invoking: GCC C Compiler'
- gcc -I../include -O0 -g3 -Wall -Wextra $(CPPFLAGS) $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
- @echo 'Finished building: $<'
- @echo ' '
-
-
+++ /dev/null
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
-# Add inputs and outputs from these tool invocations to the build variables
-C_SRCS += \
-../src/strextra/strextra.c
-
-OBJS += \
-./src/strextra/strextra.o
-
-C_DEPS += \
-./src/strextra/strextra.d
-
-
-# Each subdirectory must supply rules for building sources it contributes
-src/strextra/%.o: ../src/strextra/%.c
- @echo 'Building file: $<'
- @echo 'Invoking: GCC C Compiler'
- gcc -I../include -O0 -g3 -Wall -Wextra $(CPPFLAGS) $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
- @echo 'Finished building: $<'
- @echo ' '
-
-
-include src/xpath/subdir.mk
-include src/xmath/subdir.mk
-include src/timeit/subdir.mk
--include src/strextra/subdir.mk
--include src/slist/subdir.mk
--include src/siri/admin/subdir.mk
+-include src/xstr/subdir.mk
+-include src/vec/subdir.mk
+-include src/siri/service/subdir.mk
-include src/siri/parser/subdir.mk
-include src/siri/net/subdir.mk
-include src/siri/help/subdir.mk
src/owcrypt \
src/procinfo \
src/qpack \
-src/siri/admin \
+src/siri/service \
src/siri/args \
src/siri \
src/siri/cfg \
src/siri/grammar \
src/siri/help \
src/siri/net \
-src/slist \
-src/strextra \
+src/vec \
+src/xstr \
src/timeit \
src/xmath \
src/xpath \
+++ /dev/null
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
-# Add inputs and outputs from these tool invocations to the build variables
-C_SRCS += \
-../src/siri/admin/account.c \
-../src/siri/admin/client.c \
-../src/siri/admin/request.c
-
-OBJS += \
-./src/siri/admin/account.o \
-./src/siri/admin/client.o \
-./src/siri/admin/request.o
-
-C_DEPS += \
-./src/siri/admin/account.d \
-./src/siri/admin/client.d \
-./src/siri/admin/request.d
-
-
-# Each subdirectory must supply rules for building sources it contributes
-src/siri/args/%.o: ../src/siri/args/%.c
- @echo 'Building file: $<'
- @echo 'Invoking: GCC C Compiler'
- gcc -DNDEBUG -I../include -O3 -Wall -Wextra $(CPPFLAGS) $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
- @echo 'Finished building: $<'
- @echo ' '
-
-
--- /dev/null
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+C_SRCS += \
+../src/siri/service/account.c \
+../src/siri/service/client.c \
+../src/siri/service/request.c
+
+OBJS += \
+./src/siri/service/account.o \
+./src/siri/service/client.o \
+./src/siri/service/request.o
+
+C_DEPS += \
+./src/siri/service/account.d \
+./src/siri/service/client.d \
+./src/siri/service/request.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+src/siri/args/%.o: ../src/siri/args/%.c
+ @echo 'Building file: $<'
+ @echo 'Invoking: GCC C Compiler'
+ gcc -DNDEBUG -I../include -O3 -Wall -Wextra $(CPPFLAGS) $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
+ @echo 'Finished building: $<'
+ @echo ' '
+
+
+++ /dev/null
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
-# Add inputs and outputs from these tool invocations to the build variables
-C_SRCS += \
-../src/slist/slist.c
-
-OBJS += \
-./src/slist/slist.o
-
-C_DEPS += \
-./src/slist/slist.d
-
-
-# Each subdirectory must supply rules for building sources it contributes
-src/slist/%.o: ../src/slist/%.c
- @echo 'Building file: $<'
- @echo 'Invoking: GCC C Compiler'
- gcc -DNDEBUG -I../include -O3 -Wall -Wextra $(CPPFLAGS) $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
- @echo 'Finished building: $<'
- @echo ' '
-
-
+++ /dev/null
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
-# Add inputs and outputs from these tool invocations to the build variables
-C_SRCS += \
-../src/strextra/strextra.c
-
-OBJS += \
-./src/strextra/strextra.o
-
-C_DEPS += \
-./src/strextra/strextra.d
-
-
-# Each subdirectory must supply rules for building sources it contributes
-src/strextra/%.o: ../src/strextra/%.c
- @echo 'Building file: $<'
- @echo 'Invoking: GCC C Compiler'
- gcc -DNDEBUG -I../include -O3 -Wall -Wextra $(CPPFLAGS) $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
- @echo 'Finished building: $<'
- @echo ' '
-
-
- * Fixed wrapping imap to slist functions with appropriate locks.
+ * Fixed wrapping imap to vec functions with appropriate locks.
(see issue #51)
\ No newline at end of file
SiriDB Admin Tool can be used to talk with the new API and provides both a
command-line and a graphical web interface. Pre-compiled versions for
different platforms can be found and downloaded from:
- https://github.com/transceptor-technology/siridb-admin/releases/latest
+ https://github.com/transceptor-technology/siridb-service/releases/latest
* Added version check before creating a new pool or replica. (issue #62)
\ No newline at end of file
siridb_servers_list(): int
siridb_servers_load(): int
siridb_servers_online(): int
-siridb_servers_other2slist(): *slist_t
+siridb_servers_other2vec(): *vec_t
siridb_servers_register(): int
siridb_servers_save(): int
siridb_servers_send_flags(): void
fn: *char
groups: *ct_t
mutex: uv_mutex_t
-ngroups: *slist_t
-nseries: *slist_t
+ngroups: *vec_t
+nseries: *vec_t
ref: uint8_t
status: uint8_t
work: uv_work_t
ref: uint16_t
regex: *pcre
regex_extra: *pcre_extra
-series: *slist_t
+series: *vec_t
source: *char
--
siridb__group_decref(): void
/*
- * argparse.h - module for parsing command line arguments.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-03-2016
- *
+ * argparse.h - Module for parsing command line arguments.
*/
#ifndef ARGPARSE_H_
#define ARGPARSE_H_
/*
* cexpr.h - Conditional expressions.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 13-06-2016
- *
*/
#ifndef CEXPR_H_
#define CEXPR_H_
/*
- * cfgparser.h - module for reading (and later writing) to INI style files.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-03-2016
- *
+ * cfgparser.h - Reading (and later writing) to INI style files.
*/
#ifndef CFGPARSER_H_
#define CFGPARSER_H_
/*
* ctree.h - Compact Binary Tree implementation.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 18-03-2016
- *
*/
#ifndef CTREE_H_
#define CTREE_H_
/*
- * expr.h - Parse expression
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 19-04-2016
- *
+ * expr.h - For parsing expressions.
*/
#ifndef EXPR_H_
#define EXPR_H_
/*
- * imap.h - map for uint64_t integer keys
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 03-08-2016
- *
+ * imap.h - Lookup map for uint64_t integer keys with set operation support.
*/
#ifndef IMAP_H_
#define IMAP_H_
#include <inttypes.h>
#include <stddef.h>
-#include <slist/slist.h>
+#include <vec/vec.h>
typedef int (*imap_cb)(void * data, void * args);
typedef int (*imap_free_cb)(void * data);
void * imap_pop(imap_t * imap, uint64_t id);
int imap_walk(imap_t * imap, imap_cb cb, void * data);
void imap_walkn(imap_t * imap, size_t * n, imap_cb cb, void * data);
-slist_t * imap_slist(imap_t * imap);
-slist_t * imap_slist_pop(imap_t * imap);
-slist_t * imap_2slist(imap_t * imap);
-slist_t * imap_2slist_ref(imap_t * imap);
+vec_t * imap_vec(imap_t * imap);
+vec_t * imap_vec_pop(imap_t * imap);
+vec_t * imap_2vec(imap_t * imap);
+vec_t * imap_2vec_ref(imap_t * imap);
void imap_union_ref(
imap_t * dest,
imap_t * imap,
struct imap_s
{
size_t len;
- slist_t * slist;
+ vec_t * vec;
imap_node_t nodes[];
};
/*
- * iso8601.h - Library to parse ISO 8601 dates
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 21-04-2016
- *
+ * iso8601.h - Library to parse ISO 8601 dates. Time-zones are found with
+ * tzset() in either /usr/lib/zoneinfo/ or /usr/share/zoneinfo/.
*/
#ifndef ISO8601_H_
#define ISO8601_H_
/*
- * llist.h - Linked List
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 03-05-2016
- *
+ * llist.h - Linked List implementation.
*/
#ifndef LLIST_H_
#define LLIST_H_
typedef struct llist_node_s llist_node_t;
#include <stdio.h>
-#include <slist/slist.h>
+#include <vec/vec.h>
typedef int (*llist_cb)(void * data, void * args);
int llist_append(llist_t * llist, void * data);
int llist_walk(llist_t * llist, llist_cb cb, void * args);
void llist_walkn(llist_t * llist, size_t * n, llist_cb cb, void * args);
-slist_t * llist2slist(llist_t * llist);
+vec_t * llist2vec(llist_t * llist);
void * llist_get(llist_t * llist, llist_cb cb, void * args);
void * llist_remove(llist_t * llist, llist_cb cb, void * args);
void * llist_pop(llist_t * llist);
/*
- * lock.h - SiriDB Lock.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 13-07-2016
- *
+ * lock.h - Lock a directory by using a lock file.
*/
#ifndef LOCK_H_
#define LOCK_H_
/*
- * logger.h - log module
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-03-2016
- *
+ * logger.h - Logging module.
*/
#ifndef LOGGER_H_
#define LOGGER_H_
/*
* owcrypt.h - One Way Encryption. (used for storing a database user password)
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2017, Transceptor Technology
- *
- * changes
- * - initial version, 24-02-2017
- *
*/
#ifndef OWCRYPT_H_
#define OWCRYPT_H_
* http://stackoverflow.com/questions/63166/how-to-determine-cpu-and-
* memory-consumption-from-inside-a-process
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 18-03-2016
- *
*/
#ifndef PROCINFO_H_
/*
- * qpack.h - efficient binary serialization format
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 11-03-2016
- *
+ * qpack.h - Efficient binary serialization format.
*/
#ifndef QPACK_H_
#define QPACK_H_
+++ /dev/null
-/*
- * account.h - SiriDB Administrative User.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2017, Transceptor Technology
- *
- * changes
- * - initial version, 16-03-2017
- *
- */
-#ifndef SIRI_ADMIN_ACCOUNT_H_
-#define SIRI_ADMIN_ACCOUNT_H_
-
-typedef struct siri_admin_account_s siri_admin_account_t;
-
-#include <qpack/qpack.h>
-#include <siri/siri.h>
-
-int siri_admin_account_init(siri_t * siri);
-void siri_admin_account_destroy(siri_t * siri);
-int siri_admin_account_new(
- siri_t * siri,
- qp_obj_t * qp_account,
- qp_obj_t * qp_password,
- int is_encrypted,
- char * err_msg);
-int siri_admin_account_check(
- siri_t * siri,
- qp_obj_t * qp_account,
- qp_obj_t * qp_password,
- char * err_msg);
-int siri_admin_account_change_password(
- siri_t * siri,
- qp_obj_t * qp_account,
- qp_obj_t * qp_password,
- char * err_msg);
-int siri_admin_account_drop(
- siri_t * siri,
- qp_obj_t * qp_account,
- char * err_msg);
-int siri_admin_account_save(siri_t * siri, char * err_msg);
-
-struct siri_admin_account_s
-{
- char * account;
- char * password; /* keeps an encrypted password */
-};
-
-#endif /* SIRI_ADMIN_ACCOUNT_H_ */
+++ /dev/null
-/*
- * client.h - Client for expanding a siridb database.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2017, Transceptor Technology
- *
- * changes
- * - initial version, 24-03-2017
- *
- */
-#ifndef SIRI_ADMIN_CLIENT_H_
-#define SIRI_ADMIN_CLIENT_H_
-
-typedef struct siri_admin_client_s siri_admin_client_t;
-
-#include <inttypes.h>
-#include <uv.h>
-#include <qpack/qpack.h>
-#include <uuid/uuid.h>
-#include <siri/net/pkg.h>
-
-int siri_admin_client_request(
- uint16_t pid,
- uint16_t port,
- int pool,
- uuid_t * uuid,
- qp_obj_t * host,
- qp_obj_t * username,
- qp_obj_t * password,
- qp_obj_t * dbname,
- const char * dbpath,
- sirinet_stream_t * client,
- char * err_msg);
-
-void siri_admin_client_free(siri_admin_client_t * adm_client);
-
-struct siri_admin_client_s
-{
- uint8_t request;
- uint8_t flags;
- uint16_t pid;
- uint16_t port;
- uuid_t uuid;
- int pool; /* -1 for a new pool */
- char * host;
- char * username;
- char * password;
- char * dbname;
- char * dbpath;
- sirinet_stream_t * client;
- sirinet_pkg_t * pkg;
-};
-
-#endif /* SIRI_ADMIN_CLIENT_H_ */
+++ /dev/null
-/*
- * request.h - SiriDB Administrative Request.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2017, Transceptor Technology
- *
- * changes
- * - initial version, 16-03-2017
- *
- */
-#ifndef SIRI_ADMIN_REQUEST_H_
-#define SIRI_ADMIN_REQUEST_H_
-
-typedef enum
-{
- ADMIN_NEW_ACCOUNT_,
- ADMIN_CHANGE_PASSWORD_,
- ADMIN_DROP_ACCOUNT_,
- ADMIN_NEW_DATABASE_,
- ADMIN_NEW_POOL,
- ADMIN_NEW_REPLICA,
- ADMIN_GET_VERSION=64,
- ADMIN_GET_ACCOUNTS,
- ADMIN_GET_DATABASES
-} admin_request_t;
-
-#include <qpack/qpack.h>
-#include <siri/net/protocol.h>
-
-int siri_admin_request_init(void);
-void siri_admin_request_destroy(void);
-cproto_server_t siri_admin_request(
- int tp,
- qp_unpacker_t * qp_unpacker,
- qp_obj_t * qp_account,
- qp_packer_t ** packaddr,
- uint16_t pid,
- sirinet_stream_t * client,
- char * err_msg);
-void siri_admin_request_rollback(const char * dbpath);
-
-
-#endif /* SIRI_ADMIN_REQUEST_H_ */
/*
- * args.h - SiriDB Arguments.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2017, Transceptor Technology
- *
- * changes
- * - initial version, 16-03-2017
+ * args.h - Parse SiriDB command line arguments.
*/
#ifndef SIRI_ARGS_H_
#define SIRI_ARGS_H_
/*
- * async.h - SiriDB async wrapper
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- *
- * changes
- * - initial version, 21-07-2016
- *
+ * async.h - SiriDB async wrapper.
*/
#ifndef SIRI_ASYC_H_
#define SIRI_ASYC_H_
/*
* backup.h - Set SiriDB in backup mode.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 27-09-2016
- *
*/
#ifndef SIRI_BACKUP_H_
#define SIRI_BACKUP_H_
/*
* buffersync.h - Buffer sync.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2018, Transceptor Technology
- *
*/
#ifndef SIRI_BUFFERSYNC_H_
#define SIRI_BUFFERSYNC_H_
/*
- * cfg.h - SiriDB Config.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2017, Transceptor Technology
- *
- * changes
- * - initial version, 16-03-2017
+ * cfg.h - Read the global SiriDB configuration file. (usually siridb.conf)
*/
#ifndef SIRI_CFG_H_
#define SIRI_CFG_H_
/*
* access.h - Access constants and functions.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 13-03-2016
- *
*/
#ifndef SIRIDB_ACCESS_H_
#define SIRIDB_ACCESS_H_
/*
* aggregate.h - SiriDB aggregation methods.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 15-04-2016
- *
*/
#ifndef SIRIDB_AGGREGATE_H_
#define SIRIDB_AGGREGATE_H_
#include <siri/db/points.h>
#include <siri/grammar/gramp.h>
-#include <slist/slist.h>
+#include <vec/vec.h>
#include <cexpr/cexpr.h>
#include <qpack/qpack.h>
#include <pcre2.h>
siridb_aggr_t * aggr,
char * err_msg);
void siridb_init_aggregates(void);
-slist_t * siridb_aggregate_list(cleri_children_t * children, char * err_msg);
-void siridb_aggregate_list_free(slist_t * alist);
+vec_t * siridb_aggregate_list(cleri_children_t * children, char * err_msg);
+void siridb_aggregate_list_free(vec_t * alist);
int siridb_aggregate_can_skip(cleri_children_t * children);
struct siridb_aggr_s
/*
* auth.h - Handle SiriDB authentication.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-03-2016
- *
*/
#ifndef SIRIDB_AUTH_H_
#define SIRIDB_AUTH_H_
/*
- * buffer.h - Buffer for integer and double series.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 01-04-2016
- *
+ * buffer.h - Buffer for integer and double values.
*/
#ifndef SIRIDB_BUFFER_H_
#define SIRIDB_BUFFER_H_
size_t len; /* number of points allocated per series */
char * template; /* template for writing an empty buffer */
char * path; /* path where the buffer file is stored */
- slist_t * empty; /* list with empty buffer spaces */
+ vec_t * empty; /* list with empty buffer spaces */
FILE * fp; /* buffer file pointer */
int fd; /* buffer file descriptor */
};
/*
- * db.h - contains functions and constants for a SiriDB database.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-03-2016
- *
+ * db.h - SiriDB database.
*/
#ifndef SIRIDB_H_
#define SIRIDB_H_
/*
* ffile.h - FIFO file.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 30-06-2016
- *
*/
#ifndef SIRIDB_FFILE_H_
#define SIRIDB_FFILE_H_
/*
* fifo.h - First in, first out file buffer.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 30-06-2016
- *
*/
#ifndef SIRIDB_FIFO_H_
#define SIRIDB_FIFO_H_
/*
- * forward.h - Handle forwarding series while re-indexing
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 31-07-2016
- *
+ * forward.h - Handle forwarding series while re-indexing.
*/
#ifndef SIRIDB_FORWARD_H_
#define SIRIDB_FORWARD_H_
/*
* group.h - Group (saved regular expressions).
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 16-08-2016
- *
*/
#ifndef SIRIDB_GROUP_H_
#define SIRIDB_GROUP_H_
typedef struct siridb_group_s siridb_group_t;
-#include <slist/slist.h>
+#include <vec/vec.h>
#include <siri/db/series.h>
#include <pcre2.h>
uint32_t n; /* total series (needs an update from all pools) */
char * name;
char * source; /* pattern/flags representation */
- slist_t * series;
+ vec_t * series;
pcre2_code * regex;
pcre2_match_data * match_data;
};
/*
* groups.h - Groups (saved regular expressions).
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
+ * Info groups->mutex:
*
- * changes
- * - initial version, 16-08-2016
+ * Main thread:
+ * groups->groups : read (no lock) write (lock)
+ * groups->nseries : read (lock) write (lock)
+ * groups->ngroups : read (lock) write (lock)
+ * group->series : read (lock) write (not allowed)
+
+ * Other threads:
+ * groups->groups : read (lock) write (not allowed)
+ * groups->nseries : read (lock) write (lock)
+ * groups->ngroups : read (lock) write (lock)
+ *
+ * Group thread:
+ * group->series : read (no lock) write (lock)
*
+ * Note: One exception to 'not allowed' are the free functions
+ * since they only run when no other references to the object exist.
*/
#ifndef SIRIDB_GROUPS_H_
#define SIRIDB_GROUPS_H_
#define GROUPS_FLAG_DROPPED_SERIES 1
#include <ctree/ctree.h>
-#include <slist/slist.h>
+#include <vec/vec.h>
#include <uv.h>
#include <siri/db/db.h>
#include <siri/net/pkg.h>
uint8_t ref;
char * fn;
ct_t * groups;
- slist_t * nseries; /* list of series we need to assign to groups */
- slist_t * ngroups; /* list of groups which need initialization */
+ vec_t * nseries; /* list of series we need to assign to groups */
+ vec_t * ngroups; /* list of groups which need initialization */
uv_mutex_t mutex;
uv_work_t work;
};
/*
- * initsync.h - Initial replica synchronization
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 22-07-2016
- *
+ * initsync.h - Initial replica synchronization.
*/
#ifndef SIRIDB_INITSYNC_H_
#define SIRIDB_INITSYNC_H_
/*
* insert.h - Handler database inserts.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 24-03-2016
- *
*/
#ifndef SIRIDB_INSERT_H_
#define SIRIDB_INSERT_H_
/*
- * listener.h - contains functions for processing queries.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-03-2016
- *
+ * listener.h - Contains functions for processing queries.
*/
#ifndef SIRIDB_LISTENER_H_
#define SIRIDB_LISTENER_H_
/*
- * lookup.h - SiriDB Pool lookup.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 29-07-2016
- *
+ * lookup.h - Find and assign to which pool series belong.
*/
#ifndef SIRIDB_LOOKUP_H_
#define SIRIDB_LOOKUP_H_
/*
* median.h - Calculate median, median high and median low.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 16-04-2016
- *
*/
#ifndef SIRIDB_MEDIAN_H_
#define SIRIDB_MEDIAN_H_
/*
* misc.h - Miscellaneous functions used by SiriDB.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 18-08-2016
- *
*/
#ifndef SIRIDB_MISC_H_
#define SIRIDB_MISC_H_
/*
- * node.h - contains logic for cleri nodes which we need to parse.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-03-2016
- *
+ * nodes.h - Contains logic for cleri nodes which we need to parse.
*/
#ifndef SIRIDB_NODES_H_
#define SIRIDB_NODES_H_
/*
- * pcache.h - Points structure with notion or its size
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-10-2016
- *
+ * pcache.h - Points structure with notion of its size.
*/
#ifndef SIRIDB_PCACHE_H_
#define SIRIDB_PCACHE_H_
/*
* points.h - Array object for points.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 04-04-2016
- *
*/
#ifndef SIRIDB_POINTS_H_
#define SIRIDB_POINTS_H_
#include <stdlib.h>
#include <inttypes.h>
#include <qpack/qpack.h>
-#include <slist/slist.h>
+#include <vec/vec.h>
void siridb_points_init(void);
siridb_points_t * siridb_points_new(size_t size, points_tp tp);
int siridb_points_pack(siridb_points_t * points, qp_packer_t * packer);
void siridb_points_ts_correction(siridb_points_t * points, double factor);
int siridb_points_raw_pack(siridb_points_t * points, qp_packer_t * packer);
-siridb_points_t * siridb_points_merge(slist_t * plist, char * err_msg);
+siridb_points_t * siridb_points_merge(vec_t * plist, char * err_msg);
unsigned char * siridb_points_zip_double(
siridb_points_t * points,
uint_fast32_t start,
/*
- * pool.h - Generate pool lookup.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 25-03-2016
- *
+ * pool.h - SiriDB pool containing one or two servers.
*/
#ifndef SIRIDB_POOL_H_
#define SIRIDB_POOL_H_
/*
- * pools.h - Generate pools lookup.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 25-03-2016
- *
+ * pools.h - Collection of pools.
*/
#ifndef SIRIDB_POOLS_H_
#define SIRIDB_POOLS_H_
#include <siri/net/pkg.h>
#include <siri/net/promise.h>
#include <siri/net/promises.h>
-#include <slist/slist.h>
+#include <vec/vec.h>
#include <siri/db/lookup.h>
void siridb_pools_init(siridb_t * siridb);
void * data,
int flags);
void siridb_pools_send_pkg_2some(
- slist_t * slist,
+ vec_t * vec,
sirinet_pkg_t * pkg,
uint64_t timeout,
sirinet_promises_cb cb,
/*
* presuf.h - Prefix and Suffix store.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-08-2016
- *
*/
#ifndef SIRIDB_PRESUF_H_
#define SIRIDB_PRESUF_H_
/*
* props.h - Functions to return SiriDB properties.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 17-03-2016
- *
*/
#ifndef SIRIDB_PROPS_H_
#define SIRIDB_PROPS_H_
/*
- * queries.h - Querie helpers for listener
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 03-05-2016
- *
+ * queries.h - Query helpers for listener.
*/
#ifndef SIRIDB_QUERIES_H_
#define SIRIDB_QUERIES_H_
#include <uv.h>
#include <inttypes.h>
#include <imap/imap.h>
-#include <slist/slist.h>
+#include <vec/vec.h>
#include <cexpr/cexpr.h>
#include <cleri/cleri.h>
#include <ctree/ctree.h>
imap_t * series_map; \
imap_t * series_tmp; \
imap_t * pmap; \
-slist_t * slist; \
-size_t slist_index; \
+vec_t * vec; \
+size_t vec_index; \
imap_update_cb update_cb; \
cexpr_t * where_expr; \
pcre2_code * regex; \
{
QUERY_DEF
size_t n; /* keep a counter for number of drops. */
- slist_t * shards_list;
+ vec_t * shards_list;
};
struct query_list_s
{
QUERY_DEF
- slist_t * props; /* will be freed */
+ vec_t * props; /* will be freed */
size_t limit;
};
char * merge_as;
ct_t * result;
imap_t * points_map; /* points_map for caching */
- slist_t * alist; /* aggregation list (can be used multiple times)*/
- slist_t * mlist; /* merge aggregation list */
+ vec_t * alist; /* aggregation list (can be used multiple times)*/
+ vec_t * mlist; /* merge aggregation list */
};
#endif /* SIRIDB_QUERIES_H_ */
/*
* query.h - Responsible for parsing queries.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-03-2016
- *
*/
#ifndef SIRIDB_QUERY_H_
#define SIRIDB_QUERY_H_
/*
- * re.h - Helpers for regular expressions
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 04-08-2016
- *
+ * re.h - Helpers for regular expressions.
*/
#ifndef SIRIDB_RE_H_
#define SIRIDB_RE_H_
/*
* reindex.h - SiriDB Re-index.
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
+ * Differences while re-indexing:
*
- * changes
- * - initial version, 27-07-2016
+ * - Group information like number of series will be updated at a lower
+ * interval which leads to probably incorrect number of series per group.
+ * Selections for series in a group or a list of series per group are still
+ * correct and can only lack of brand new series. (newer than 30 seconds)
*
+ * - Selecting an unknown series usually raises a QueryError but we do not
+ * raise this error during re-indexing since the series might be in either
+ * the old- or new pool. (selecting series during re-indexing has therefore
+ * the same behavior as a regular expression selection)
+ *
+ * - Drop server is not allowed while re-indexing.
*/
#ifndef SIRIDB_REINDEX_H_
#define SIRIDB_REINDEX_H_
/*
* replicate.h - Replicate SiriDB.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- *
- * changes
- * - initial version, 11-07-2016
- *
*/
#ifndef SIRIDB_REPLICATE_H_
#define SIRIDB_REPLICATE_H_
/*
- * series.h - Series
+ * series.c - SiriDB Time Series.
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
*
- * changes
- * - initial version, 29-03-2016
+ * Info siridb->series_mutex:
*
+ * Main thread:
+ * siridb->series_map : read (no lock) write (lock)
+ * series->idx : read (lock) write (lock)
+ *
+ * Other threads:
+ * siridb->series_map : read (lock) write (not allowed)
+ * series->idx : read (lock) write (lock)
+ *
+ * Note: One exception to 'not allowed' are the free functions
+ * since they only run when no other references to the object exist.
*/
#ifndef SIRIDB_SERIES_H_
#define SIRIDB_SERIES_H_
/*
- * server.h - SiriDB Server.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 17-03-2016
- *
+ * server.h - Each SiriDB database has at least one server.
*/
#ifndef SIRIDB_SERVER_H_
#define SIRIDB_SERVER_H_
/*
- * servers.h - SiriDB Servers.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-06-2016
- *
+ * servers.h - Collection of SiriDB servers.
*/
#ifndef SIRIDB_SERVERS_H_
#define SIRIDB_SERVERS_H_
siridb_server_t * replica);
void siridb_servers_send_pkg(
- slist_t * servers,
+ vec_t * servers,
sirinet_pkg_t * pkg,
uint64_t timeout,
sirinet_promises_cb cb,
int siridb_servers_check_version(siridb_t * siridb, char * version);
int siridb_servers_save(siridb_t * siridb);
int siridb_servers_register(siridb_t * siridb, siridb_server_t * server);
-slist_t * siridb_servers_other2slist(siridb_t * siridb);
+vec_t * siridb_servers_other2vec(siridb_t * siridb);
#endif /* SIRIDB_SERVERS_H_ */
/*
- * shard.h - SiriDB Shard.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 04-04-2016
- *
+ * shard.h - SiriDB shard file.
*/
#ifndef SIRIDB_SHARD_H_
#define SIRIDB_SHARD_H_
/*
- * shards.h - SiriDB shards.
+ * shards.h - Collection of SiriDB shards.
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
+ * Info shards->mutex:
*
- * changes
- * - initial version, 04-04-2016
+ * Main thread:
+ * siridb->shards : read (lock) write (lock)
+
+ * Other threads:
+ * siridb->shards : read (lock) write (lock)
*
+ * Note: since series->idx hold a reference to a shard, a lock to the
+ * series_mutex is required in some cases.
*/
#ifndef SIRIDB_SHARDS_H_
#define SIRIDB_SHARDS_H_
/*
- * tasks.h - SiriDB Error.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 31-10-2016
- *
+ * tasks.f - Counters for info on SiriDB tasks.
*/
#ifndef SIRIDB_TASKS_H_
#define SIRIDB_TASKS_H_
/*
* time.h - Time- and time precision functions and constants.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 09-03-2016
- *
*/
#ifndef SIRIDB_TIME_H_
#define SIRIDB_TIME_H_
/*
- * user.h - contains functions for a SiriDB database member.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-03-2016
- *
+ * user.h - Contains functions for a SiriDB database user.
*/
#ifndef SIRIDB_USER_H_
#define SIRIDB_USER_H_
/*
- * users.h - contains functions for a SiriDB database members.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 04-05-2016
- *
+ * users.h - Collection of database users.
*/
#ifndef SIRIDB_USERS_H_
#define SIRIDB_USERS_H_
/*
* variance.h - Calculate variance for points.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-08-2016
- *
*/
#ifndef SIRIDB_VARIANCE_H_
#define SIRIDB_VARIANCE_H_
/*
- * walker.h - creates enter and exit nodes
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 13-06-2016
- *
+ * walker.h - Creates enter and exit nodes.
*/
#ifndef SIRIDB_WALKER_H_
#define SIRIDB_WALKER_H_
/*
- * error.h - SiriDB Error.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 30-06-2016
- *
+ * err.h - SiriDB Error.
*/
#ifndef SIRI_ERR_H_
#define SIRI_ERR_H_
/*
- * filehandler.h - Filehandler for shard files.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-04-2016
- *
+ * handler.h - File handler for shard files.
*/
#ifndef SIRI_FH_H_
#define SIRI_FH_H_
/*
- * filepointer.h - File-pointer used in combination with file-handler.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-04-2016
- *
+ * pointer.h - File pointer used in combination with file handler.
*/
#ifndef SIRI_FP_H_
#define SIRI_FP_H_
/*
* gramp.h - SiriDB Grammar Properties.
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
* Note: we need this file up-to-date with the grammar. The grammar has
* keywords starting with K_ so the will all be sorted.
* KW_OFFSET should be set to the first keyword and KW_COUNT needs the
* last keyword in the grammar.
*
- * changes
- * - initial version, 15-04-2016
- *
*/
#ifndef SIRI_GRAMP_H_
#define SIRI_GRAMP_H_
/*
* heartbeat.h - Heart-beat task SiriDB.
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
* There is one and only one heart-beat task thread running for SiriDB. For
* this reason we do not need to parse data but we should only take care for
* locks while writing data.
- *
- * changes
- * - initial version, 17-06-2016
- *
*/
#ifndef SIRI_HEARTBEAT_H_
#define SIRI_HEARTBEAT_H_
/*
- * help.h - Help for SiriDB
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 23-09-2016
- *
+ * help.h - Help for SiriDB.
*/
#ifndef SIRI_HELP_H_
#define SIRI_HELP_H_
/*
- * bserver.h - Back-end Server SiriDB.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- *
- * changes
- * - initial version, 18-06-2016
- *
+ * bserver.h - Listen to back-end SiriDB Server.
*/
#ifndef SIRINET_BSERVER_H_
#define SIRINET_BSERVER_H_
/*
- * clserver.h - TCP server for serving client requests.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 09-03-2016
- *
+ * clserver.h - Listen for client requests.
*/
#ifndef SIRINET_CLSERVER_H_
#define SIRINET_CLSERVER_H_
+/*
+ * pipe.h - Named Pipe support.
+ */
#ifndef SIRINET_PIPE_H_
#define SIRINET_PIPE_H_
/*
* pkg.h - SiriDB Package type.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 18-06-2016
- *
*/
#ifndef SIRINET_PKG_H_
#define SIRINET_PKG_H_
/*
- * promise.h - Promise SiriDB.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- *
- * changes
- * - initial version, 21-06-2016
- *
+ * promise.c - Promise used for sending to data to SiriDB servers.
*/
#ifndef SIRINET_PROMISE_H_
#define SIRINET_PROMISE_H_
/*
- * promises.h - Promises SiriDB.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- *
- * changes
- * - initial version, 13-07-2016
- *
+ * promises.h - Collection for promised.
*/
#ifndef SIRINET_PROMISES_H_
#define SIRINET_PROMISES_H_
typedef struct sirinet_promises_s sirinet_promises_t;
-#include <slist/slist.h>
+#include <vec/vec.h>
typedef void (* sirinet_promises_cb)(
- slist_t * promises,
+ vec_t * promises,
void * data);
#include <siri/net/promise.h>
sirinet_promises_cb cb,
void * data,
sirinet_pkg_t * pkg);
-void sirinet_promises_llist_free(slist_t * promises);
+void sirinet_promises_llist_free(vec_t * promises);
void sirinet_promises_on_response(
sirinet_promise_t * promise,
sirinet_pkg_t * pkg,
{ \
free(promises->pkg); \
promises->cb(promises->promises, promises->data); \
- slist_free(promises->promises); \
+ vec_free(promises->promises); \
free(promises); \
}
struct sirinet_promises_s
{
sirinet_promises_cb cb;
- slist_t * promises;
+ vec_t * promises;
void * data;
sirinet_pkg_t * pkg;
};
/*
- * protocol.h - Protocol for SiriDB.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 17-03-2016
- *
+ * protocol.c - Protocol definitions for SiriDB.
*/
#ifndef SIRINET_PROTOCOL_H_
#define SIRINET_PROTOCOL_H_
CPROTO_REQ_FILE_GROUPS=9, /* empty */
CPROTO_REQ_FILE_DATABASE=10, /* empty */
- /* Public Administrative API request */
- CPROTO_REQ_ADMIN=32, /* (user, password, request, {...}) */
+ /* Public Service API request */
+ CPROTO_REQ_SERVICE=32, /* (user, password, request, {...}) */
} cproto_client_t;
typedef enum
CPROTO_RES_ACK=3, /* empty */
CPROTO_RES_FILE=5, /* file content */
- /* Administrative API success */
- CPROTO_ACK_ADMIN=32, /* empty */
- CPROTO_ACK_ADMIN_DATA=33, /* [...] */
+ /* Service API success */
+ CPROTO_ACK_SERVICE=32, /* empty */
+ CPROTO_ACK_SERVICE_DATA=33, /* [...] */
/* errors 64-69 are errors with messages */
CPROTO_ERR_MSG=64, /* {"error_msg": ...} */
CPROTO_ERR_AUTH_UNKNOWN_DB=73, /* empty */
CPROTO_ERR_FILE=75, /* empty */
- /* Administrative API errors */
- CPROTO_ERR_ADMIN=96, /* {"error_msg": ...} */
- CPROTO_ERR_ADMIN_INVALID_REQUEST=97,/* empty */
+ /* Service API errors */
+ CPROTO_ERR_SERVICE=96, /* {"error_msg": ...} */
+ CPROTO_ERR_SERVICE_INVALID_REQUEST=97,/* empty */
CPROTO_DEFERRED=127 /* deferred... */
} cproto_server_t;
/*
- * stream.h - Streams, used for uv_tcp_t and uv_pipe_t.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2018, Transceptor Technology
- *
- * changes
- * - initial version, 22-08-2018
- *
+ * stream.h - For handling streams.
*/
#ifndef SIRINET_STREAM_H_
#define SIRINET_STREAM_H_
/*
- * tcp.h
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2018, Transceptor Technology
- *
- * changes
- * - initial version, 22-08-2018
- *
+ * tcp.h - TCP support.
*/
#ifndef SIRINET_TCP_H_
#define SIRINET_TCP_H_
/*
* optimize.h - Optimize task SiriDB.
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
+ * There is one and only one optimize task thread running for SiriDB. For this
+ * reason we do not need to parse data but we should only take care for locks
+ * while writing data.
*
- * changes
- * - initial version, 09-05-2016
+ * Thread debugging:
+ * log_debug("getpid: %d - pthread_self: %lu",getpid(), pthread_self());
*
*/
#ifndef SIRI_OPTIMIZE_H_
--- /dev/null
+/*
+ * account.h - SiriDB Service Account.
+ */
+#ifndef SIRI_SERVICE_ACCOUNT_H_
+#define SIRI_SERVICE_ACCOUNT_H_
+
+typedef struct siri_service_account_s siri_service_account_t;
+
+#include <qpack/qpack.h>
+#include <siri/siri.h>
+
+int siri_service_account_init(siri_t * siri);
+void siri_service_account_destroy(siri_t * siri);
+int siri_service_account_new(
+ siri_t * siri,
+ qp_obj_t * qp_account,
+ qp_obj_t * qp_password,
+ int is_encrypted,
+ char * err_msg);
+int siri_service_account_check(
+ siri_t * siri,
+ qp_obj_t * qp_account,
+ qp_obj_t * qp_password,
+ char * err_msg);
+int siri_service_account_change_password(
+ siri_t * siri,
+ qp_obj_t * qp_account,
+ qp_obj_t * qp_password,
+ char * err_msg);
+int siri_service_account_drop(
+ siri_t * siri,
+ qp_obj_t * qp_account,
+ char * err_msg);
+int siri_service_account_save(siri_t * siri, char * err_msg);
+
+struct siri_service_account_s
+{
+ char * account;
+ char * password; /* keeps an encrypted password */
+};
+
+#endif /* SIRI_SERVICE_ACCOUNT_H_ */
--- /dev/null
+/*
+ * client.h - Client for expanding a SiriDB database.
+ */
+#ifndef SIRI_SERVICE_CLIENT_H_
+#define SIRI_SERVICE_CLIENT_H_
+
+typedef struct siri_service_client_s siri_service_client_t;
+
+#include <inttypes.h>
+#include <uv.h>
+#include <qpack/qpack.h>
+#include <uuid/uuid.h>
+#include <siri/net/pkg.h>
+
+int siri_service_client_request(
+ uint16_t pid,
+ uint16_t port,
+ int pool,
+ uuid_t * uuid,
+ qp_obj_t * host,
+ qp_obj_t * username,
+ qp_obj_t * password,
+ qp_obj_t * dbname,
+ const char * dbpath,
+ sirinet_stream_t * client,
+ char * err_msg);
+
+void siri_service_client_free(siri_service_client_t * adm_client);
+
+struct siri_service_client_s
+{
+ uint8_t request;
+ uint8_t flags;
+ uint16_t pid;
+ uint16_t port;
+ uuid_t uuid;
+ int pool; /* -1 for a new pool */
+ char * host;
+ char * username;
+ char * password;
+ char * dbname;
+ char * dbpath;
+ sirinet_stream_t * client;
+ sirinet_pkg_t * pkg;
+};
+
+#endif /* SIRI_SERVICE_CLIENT_H_ */
--- /dev/null
+/*
+ * request.h - SiriDB Service Request.
+ */
+#ifndef SIRI_SERVICE_REQUEST_H_
+#define SIRI_SERVICE_REQUEST_H_
+
+typedef enum
+{
+ SERVICE_NEW_ACCOUNT_,
+ SERVICE_CHANGE_PASSWORD_,
+ SERVICE_DROP_ACCOUNT_,
+ SERVICE_NEW_DATABASE_,
+ SERVICE_NEW_POOL,
+ SERVICE_NEW_REPLICA,
+ SERVICE_GET_VERSION=64,
+ SERVICE_GET_ACCOUNTS,
+ SERVICE_GET_DATABASES
+} service_request_t;
+
+#include <qpack/qpack.h>
+#include <siri/net/protocol.h>
+
+int siri_service_request_init(void);
+void siri_service_request_destroy(void);
+cproto_server_t siri_service_request(
+ int tp,
+ qp_unpacker_t * qp_unpacker,
+ qp_obj_t * qp_account,
+ qp_packer_t ** packaddr,
+ uint16_t pid,
+ sirinet_stream_t * client,
+ char * err_msg);
+void siri_service_request_rollback(const char * dbpath);
+
+
+#endif /* SIRI_SERVICE_REQUEST_H_ */
/*
- * siri.h - global methods for SiriDB.
+ * siri.h - Root for SiriDB.
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
*
- * changes
- * - initial version, 08-03-2016
+ * Info siri->siridb_mutex:
+ *
+ * Main thread:
+ * siri->siridb_list : read (no lock) write (lock)
+ *
+ * Other threads:
+ * siri->siridb_list : read (lock) write (not allowed)
*
*/
#ifndef SIRI_H_
uv_mutex_t siridb_mutex;
uint32_t startup_time;
- /* initialized by sidi_admin_account_init */
+ /* initialized by sidi_service_account_init */
llist_t * accounts;
- /* initialized by sidi_admin_request_init */
+ /* initialized by sidi_service_request_init */
pcre2_code * dbname_regex;
pcre2_match_data * dbname_match_data;
/*
- * version.h - contains SiriDB version info.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-03-2016
- *
+ * version.h - SiriDB version info.
*/
#ifndef SIRI_VERSION_H_
#define SIRI_VERSION_H_
+++ /dev/null
-/*
- * slist.h - Simple List
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 06-06-2016
- *
- */
-#ifndef SLIST_H_
-#define SLIST_H_
-
-#define SLIST_DEFAULT_SIZE 8
-
-typedef struct slist_s slist_t;
-typedef struct slist_object_s slist_object_t;
-
-#include <stdio.h>
-#include <stddef.h>
-#include <inttypes.h>
-
-slist_t * slist_new(size_t size);
-slist_t * slist_copy(slist_t * source);
-void slist_compact(slist_t ** slist);
-int slist_append_safe(slist_t ** slist, void * data);
-
-/*
- * Expects the object to have a object->ref (uint_xxx_t) on top of the
- * objects definition.
- */
-#define slist_object_incref(object) ((slist_object_t * ) object)->ref++
-
-/*
- * Expects the object to have a object->ref (uint_xxx_t) on top of the
- * objects definition.
- *
- * WARNING: Be careful using 'slist_object_decref' only when being sure
- * there are still references left on the object since an object
- * probably needs specific cleanup tasks.
- */
-#define slist_object_decref(object) ((slist_object_t * ) object)->ref--
-
-/*
- * Append data to the list. This functions assumes the list can hold the new
- * data is therefore not safe.
- */
-#define slist_append(slist, _data) slist->data[slist->len++] = _data
-
-/*
- * Destroy the simple list.
- */
-#define slist_free(slist) free(slist)
-
-/*
- * Pop the last item from the list
- */
-#define slist_pop(slist) slist->data[--slist->len]
-
-struct slist_object_s
-{
- uint32_t ref;
-};
-
-struct slist_s
-{
- size_t size;
- size_t len;
- void * data[];
-};
-
-#endif /* SLIST_H_ */
+++ /dev/null
-/*
- * strextra.h - Extra String functions used by SiriDB
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 19-03-2016
- *
- */
-#ifndef STREXTRA_H_
-#define STREXTRA_H_
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <inttypes.h>
-
-void strx_upper_case(char * sptr);
-void strx_lower_case(char * sptr);
-void strx_replace_char(char * sptr, char orig, char repl);
-int strx_replace_str(char * str, char * o, char * r, size_t n);
-void strx_split_join(char * pt, char split_chr, char join_chr);
-
-/* do not use trim when the char is created with *alloc */
-void strx_trim(char ** str, char chr);
-bool strx_is_empty(const char * str);
-bool strx_is_int(const char * str);
-bool strx_is_float(const char * str);
-bool strx_is_graph(const char * str);
-double strx_to_double(const char * src, size_t len);
-uint64_t strx_to_uint64(const char * src, size_t len);
-char * strx_dup(const char * src, size_t * n);
-
-/* important: 'dest' needs to be freed */
-size_t strx_extract_string(char * dest, const char * source, size_t len);
-
-#endif /* STREXTRA_H_ */
/*
* timeit.h - Timeit.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 16-03-2016
- *
*/
#ifndef TIMEIT_H_
#define TIMEIT_H_
--- /dev/null
+/*
+ * vec.h - Vector List.
+ */
+#ifndef VEC_H_
+#define VEC_H_
+
+#define VEC_DEFAULT_SIZE 8
+
+typedef struct vec_s vec_t;
+typedef struct vec_object_s vec_object_t;
+
+#include <stdio.h>
+#include <stddef.h>
+#include <inttypes.h>
+
+vec_t * vec_new(size_t size);
+vec_t * vec_copy(vec_t * source);
+void vec_compact(vec_t ** vec);
+int vec_append_safe(vec_t ** vec, void * data);
+
+/*
+ * Expects the object to have a object->ref (uint_xxx_t) on top of the
+ * objects definition.
+ */
+#define vec_object_incref(object) ((vec_object_t * ) object)->ref++
+
+/*
+ * Expects the object to have a object->ref (uint_xxx_t) on top of the
+ * objects definition.
+ *
+ * WARNING: Be careful using 'vec_object_decref' only when being sure
+ * there are still references left on the object since an object
+ * probably needs specific cleanup tasks.
+ */
+#define vec_object_decref(object) ((vec_object_t * ) object)->ref--
+
+/*
+ * Append data to the list. This functions assumes the list can hold the new
+ * data is therefore not safe.
+ */
+#define vec_append(vec, _data) vec->data[vec->len++] = _data
+
+/*
+ * Destroy the vector.
+ */
+#define vec_free(vec) free(vec)
+
+/*
+ * Pop the last item from the list
+ */
+#define vec_pop(vec) vec->data[--vec->len]
+
+struct vec_object_s
+{
+ uint32_t ref;
+};
+
+struct vec_s
+{
+ size_t size;
+ size_t len;
+ void * data[];
+};
+
+#endif /* VEC_H_ */
/*
- * xmath.h - Extra math functions which are useful.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 12-03-2016
- *
+ * xmath.h - Extra math functions functions used by SiriDB.
*/
#ifndef XMATH_H_
#define XMATH_H_
/*
- * xpath.h - Path and file tools
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 15-07-2016
- *
+ * xpath.h - Path and file tools.
*/
#ifndef XPATH_H_
#define XPATH_H_
--- /dev/null
+/*
+ * xstr.h - Extra String functions used by SiriDB.
+ */
+#ifndef XSTR_H_
+#define XSTR_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <inttypes.h>
+
+void xstr_upper_case(char * sptr);
+void xstr_lower_case(char * sptr);
+void xstr_replace_char(char * sptr, char orig, char repl);
+int xstr_replace_str(char * str, char * o, char * r, size_t n);
+void xstr_split_join(char * pt, char split_chr, char join_chr);
+
+/* do not use trim when the char is created with *alloc */
+void xstr_trim(char ** str, char chr);
+bool xstr_is_empty(const char * str);
+bool xstr_is_int(const char * str);
+bool xstr_is_float(const char * str);
+bool xstr_is_graph(const char * str);
+double xstr_to_double(const char * src, size_t len);
+uint64_t xstr_to_uint64(const char * src, size_t len);
+char * xstr_dup(const char * src, size_t * n);
+
+/* important: 'dest' needs to be freed */
+size_t xstr_extract_string(char * dest, const char * source, size_t len);
+
+#endif /* XSTR_H_ */
valgrind \
libuv1 \
libpcre2-8-0 && \
- wget https://github.com/SiriDB/siridb-admin/releases/download/1.1.3/siridb-admin_1.1.3_linux_amd64.bin -O /usr/local/bin/siridb-admin && \
- chmod +x /usr/local/bin/siridb-admin
+ wget https://github.com/SiriDB/siridb-service/releases/download/1.1.3/siridb-service_1.1.3_linux_amd64.bin -O /usr/local/bin/siridb-service && \
+ chmod +x /usr/local/bin/siridb-service
COPY --from=builder ./Release/siridb-server /Release/siridb-server
COPY --from=builder /usr/lib/x86_64-linux-gnu/libcleri* /usr/lib/x86_64-linux-gnu/
COPY ./itest/ /itest/
TEST_DIR = './testdir'
SIRIDBC = '../{BUILDTYPE}/siridb-server'
-ADMIN = '/usr/local/bin/siridb-admin'
+SERVICE = '/usr/local/bin/siridb-service'
VALGRIND = 'valgrind' \
' --tool=memcheck' \
' --error-exitcode=1' \
import logging
import random
import asyncio
-from .constants import ADMIN
+from .constants import SERVICE
VERBOSE = ' --verbose'
server.name))
rc = os.system(
- '{admin} '
+ '{service} '
'-u sa -p siri -s {addr} '
'new-database '
'--db-name {dbname} '
'--duration-num {duration_num} '
'--buffer-size {buffer_size}'
'{verbose}'.format(
- admin=ADMIN,
+ service=SERVICE,
addr=server.addr,
verbose=VERBOSE if self.LOG_LEVEL == 'DEBUG'
else ' >/dev/null',
remote_server = random.choice(self.servers)
rc = os.system(
- '{admin} '
+ '{service} '
'-u sa -p siri -s {addr} '
'new-replica '
'--db-name {dbname} '
'--db-password {dbpassword} '
'--pool {pool} '
'--force{verbose}'.format(
- admin=ADMIN,
+ service=SERVICE,
addr=server.addr,
dbaddr=remote_server.addr,
dbuser=username,
remote_server = random.choice(self.servers)
rc = os.system(
- '{admin} '
+ '{service} '
'-u sa -p siri -s {addr} '
'new-pool '
'--db-name {dbname} '
'--db-user {dbuser} '
'--db-password {dbpassword} '
'--force{verbose}'.format(
- admin=ADMIN,
+ service=SERVICE,
addr=server.addr,
dbaddr=remote_server.addr,
dbuser=username,
/*
* main.c - SiriDB.
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-03-2016
+ * author/maintainer : Jeroen van der Heijden <jeroen@transceptor.technology>
+ * contributors : https://github.com/SiriDB/siridb-server/contributors
+ * home page : https://siridb.net
+ * copyright : 2018, Transceptor Technology
*
*/
#include <locale.h>
/*
- * argparse.c - module for parsing command line arguments.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-03-2016
- *
+ * argparse.c - Module for parsing command line arguments.
*/
#include <argparse/argparse.h>
#include <libgen.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
#include <string.h>
#include <assert.h>
case ARGPARSE_STORE_STRING:
case ARGPARSE_STORE_INT:
strcpy(uname, current->argument->name);
- strx_replace_char(uname, '-', '_');
- strx_upper_case(uname);
+ xstr_replace_char(uname, '-', '_');
+ xstr_upper_case(uname);
if (current->argument->shortcut)
snprintf(buffer, ARGPARSE_HELP_SIZE,
"[-%c %s] ",
case ARGPARSE_STORE_STRING:
case ARGPARSE_STORE_INT:
strcpy(uname, current->argument->name);
- strx_replace_char(uname, '-', '_');
- strx_upper_case(uname);
+ xstr_replace_char(uname, '-', '_');
+ xstr_upper_case(uname);
if (current->argument->shortcut)
snprintf(buffer, ARGPARSE_HELP_SIZE,
" -%c %s,",
/*
* cexpr.c - Conditional expressions.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 13-06-2016
- *
*/
#include <cexpr/cexpr.h>
#include <assert.h>
#include <siri/db/series.h>
#include <siri/db/shard.h>
#include <siri/db/access.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
#define VIA_NULL 0
#define VIA_CEXPR 1
{
return NULL;
}
- strx_extract_string((*condition)->str, node->str, node->len);
+ xstr_extract_string((*condition)->str, node->str, node->len);
SET_CONDITION_AND_RETURN
}
/* can be a choice between keywords, in that case just wait */
/*
- * cfgparser.c - module for reading (and later writing) to INI style files.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-03-2016
- *
+ * cfgparser.c - Reading (and later writing) to INI style files.
*/
#include <cfgparser/cfgparser.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
#include <siri/err.h>
static void cfgparser_free_sections(cfgparser_section_t * root);
pt = line;
/* trims all whitespace */
- strx_trim(&pt, 0);
+ xstr_trim(&pt, 0);
if (*pt == '#' || *pt == 0)
{
if (*pt == '[' && pt[strlen(pt) - 1] == ']')
{
- strx_trim(&pt, '[');
- strx_trim(&pt, ']');
+ xstr_trim(&pt, '[');
+ xstr_trim(&pt, ']');
section = cfgparser_section(cfgparser, pt);
if (section == NULL)
{
}
- if (strx_is_int(pt))
+ if (xstr_is_int(pt))
{
option = cfgparser_integer_option(section, name, atoi(pt), 0);
}
- else if (strx_is_float(pt))
+ else if (xstr_is_float(pt))
{
sscanf(pt, "%lf", &d);
option = cfgparser_real_option(section, name, d, 0.0f);
/*
* ctree.c - Compact Binary Tree implementation.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 18-03-2016
- *
*/
#include <ctree/ctree.h>
#include <stdio.h>
/*
- * expr.c - Parse expression
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 19-04-2016
- *
+ * expr.c - For parsing expressions.
*/
#include <stdio.h>
#include <ctype.h>
/*
- * imap.c - map for uint64_t integer keys
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 03-08-2016
- *
+ * imap.c - Lookup map for uint64_t integer keys with set operation support.
*/
#include <assert.h>
#include <imap/imap.h>
static void * IMAP_pop(imap_node_t * node, uint64_t id);
static void IMAP_walk(imap_node_t * node, imap_cb cb, void * data, int * rc);
static void IMAP_walkn(imap_node_t * node, imap_cb cb, void * data, size_t * n);
-static void IMAP_2slist(imap_node_t * node, slist_t * slist);
-static void IMAP_2slist_ref(imap_node_t * node, slist_t * slist);
+static void IMAP_2vec(imap_node_t * node, vec_t * vec);
+static void IMAP_2vec_ref(imap_node_t * node, vec_t * vec);
static void IMAP_union_ref(imap_node_t * dest, imap_node_t * node);
static void IMAP_intersection_ref(
imap_node_t * dest,
}
imap->len = 0;
- imap->slist = NULL;
+ imap->vec = NULL;
return imap;
}
}
}
- slist_free(imap->slist);
+ vec_free(imap->vec);
free(imap);
}
}
}
- if (imap->slist != NULL && (
- rc < 1 || slist_append_safe(&imap->slist, data)))
+ if (imap->vec != NULL && (
+ rc < 1 || vec_append_safe(&imap->vec, data)))
{
- slist_free(imap->slist);
- imap->slist = NULL;
+ vec_free(imap->vec);
+ imap->vec = NULL;
}
return rc;
imap->len++;
}
- if (imap->slist != NULL && slist_append_safe(&imap->slist, data))
+ if (imap->vec != NULL && vec_append_safe(&imap->vec, data))
{
- slist_free(imap->slist);
- imap->slist = NULL;
+ vec_free(imap->vec);
+ imap->vec = NULL;
}
return 0;
{
imap->len--;
- if (imap->slist != NULL)
+ if (imap->vec != NULL)
{
- slist_free(imap->slist);
- imap->slist = NULL;
+ vec_free(imap->vec);
+ imap->vec = NULL;
}
}
/*
* Returns NULL in case an error has occurred.
*
- * When successful a BORROWED pointer to slist is returned.
+ * When successful a BORROWED pointer to vec is returned.
*/
-slist_t * imap_slist(imap_t * imap)
+vec_t * imap_vec(imap_t * imap)
{
- if (imap->slist == NULL)
+ if (imap->vec == NULL)
{
- imap->slist = slist_new(imap->len);
+ imap->vec = vec_new(imap->len);
- if (imap->slist != NULL && imap->len)
+ if (imap->vec != NULL && imap->len)
{
imap_node_t * nd;
uint_fast8_t i;
if (nd->data != NULL)
{
- slist_append(imap->slist, nd->data);
+ vec_append(imap->vec, nd->data);
}
if (nd->nodes != NULL)
{
- IMAP_2slist(nd, imap->slist);
+ IMAP_2vec(nd, imap->vec);
}
}
}
}
- return imap->slist;
+ return imap->vec;
}
/*
* Returns NULL in case an error has occurred.
*
- * When successful a the slist is returned and imap->slist is set to NULL.
+ * When successful a the vec is returned and imap->vec is set to NULL.
*
* This can be used when being sure this is the only time you need the list
* and prevents making a copy.
*/
-slist_t * imap_slist_pop(imap_t * imap)
+vec_t * imap_vec_pop(imap_t * imap)
{
- slist_t * slist = imap_slist(imap);
- imap->slist = NULL;
- return slist;
+ vec_t * vec = imap_vec(imap);
+ imap->vec = NULL;
+ return vec;
}
/*
* Returns NULL in case an error has occurred.
*
- * When successful a NEW slist is returned.
+ * When successful a NEW vec is returned.
*/
-slist_t * imap_2slist(imap_t * imap)
+vec_t * imap_2vec(imap_t * imap)
{
- slist_t * slist = imap_slist(imap);
- if (slist != NULL)
+ vec_t * vec = imap_vec(imap);
+ if (vec != NULL)
{
- slist = slist_copy(slist);
+ vec = vec_copy(vec);
}
- return slist;
+ return vec;
}
/*
*
* Returns NULL in case an error has occurred.
*/
-slist_t * imap_2slist_ref(imap_t * imap)
+vec_t * imap_2vec_ref(imap_t * imap)
{
- if (imap->slist == NULL)
+ if (imap->vec == NULL)
{
- imap->slist = slist_new(imap->len);
+ imap->vec = vec_new(imap->len);
- if (imap->slist != NULL && imap->len)
+ if (imap->vec != NULL && imap->len)
{
imap_node_t * nd;
uint_fast8_t i;
if (nd->data != NULL)
{
- slist_append(imap->slist, nd->data);
- slist_object_incref(nd->data);
+ vec_append(imap->vec, nd->data);
+ vec_object_incref(nd->data);
}
if (nd->nodes != NULL)
{
- IMAP_2slist_ref(nd, imap->slist);
+ IMAP_2vec_ref(nd, imap->vec);
}
}
}
else
{
size_t i;
- for (i = 0; i < imap->slist->len; i++)
+ for (i = 0; i < imap->vec->len; i++)
{
- slist_object_incref(imap->slist->data[i]);
+ vec_object_incref(imap->vec->data[i]);
}
}
- return (imap->slist == NULL) ? NULL : slist_copy(imap->slist);
+ return (imap->vec == NULL) ? NULL : vec_copy(imap->vec);
}
/*
imap_t * imap,
imap_free_cb decref_cb __attribute__((unused)))
{
- if (dest->slist != NULL)
+ if (dest->vec != NULL)
{
- slist_free(dest->slist);
- dest->slist = NULL;
+ vec_free(dest->vec);
+ dest->vec = NULL;
}
if (imap->len)
/* this must be the same object */
assert (imap_nd->data == dest_nd->data);
/* we are sure there is a ref left */
- slist_object_decref(imap_nd->data);
+ vec_object_decref(imap_nd->data);
}
else
{
}
/* cleanup source imap */
- slist_free(imap->slist);
+ vec_free(imap->vec);
free(imap);
}
imap_t * imap,
imap_free_cb decref_cb)
{
- if (dest->slist != NULL)
+ if (dest->vec != NULL)
{
- slist_free(dest->slist);
- dest->slist = NULL;
+ vec_free(dest->vec);
+ dest->vec = NULL;
}
imap_node_t * dest_nd;
}
/* cleanup source imap */
- slist_free(imap->slist);
+ vec_free(imap->vec);
free(imap);
}
imap_t * imap,
imap_free_cb decref_cb)
{
- if (dest->slist != NULL)
+ if (dest->vec != NULL)
{
- slist_free(dest->slist);
- dest->slist = NULL;
+ vec_free(dest->vec);
+ dest->vec = NULL;
}
if (imap->len)
assert (imap_nd->data == dest_nd->data);
/* we are sure to have one ref left */
- slist_object_decref(dest_nd->data);
+ vec_object_decref(dest_nd->data);
dest_nd->data = NULL;
dest->len--;
}
/* cleanup source imap */
- slist_free(imap->slist);
+ vec_free(imap->vec);
free(imap);
}
imap_t * imap,
imap_free_cb decref_cb)
{
- if (dest->slist != NULL)
+ if (dest->vec != NULL)
{
- slist_free(dest->slist);
- dest->slist = NULL;
+ vec_free(dest->vec);
+ dest->vec = NULL;
}
if (imap->len)
assert (imap_nd->data == dest_nd->data);
/* we are sure to have one ref left */
- slist_object_decref(dest_nd->data);
+ vec_object_decref(dest_nd->data);
/* but now we are not sure anymore */
(*decref_cb)(imap_nd->data);
}
/* cleanup source imap */
- slist_free(imap->slist);
+ vec_free(imap->vec);
free(imap);
}
}
}
-static void IMAP_2slist(imap_node_t * node, slist_t * slist)
+static void IMAP_2vec(imap_node_t * node, vec_t * vec)
{
imap_node_t * nd;
uint_fast8_t i;
if (nd->data != NULL)
{
- slist_append(slist, nd->data);
+ vec_append(vec, nd->data);
}
if (nd->nodes != NULL)
{
- IMAP_2slist(nd, slist);
+ IMAP_2vec(nd, vec);
}
}
}
-static void IMAP_2slist_ref(imap_node_t * node, slist_t * slist)
+static void IMAP_2vec_ref(imap_node_t * node, vec_t * vec)
{
imap_node_t * nd;
uint_fast8_t i;
if (nd->data != NULL)
{
- slist_append(slist, nd->data);
- slist_object_incref(nd->data);
+ vec_append(vec, nd->data);
+ vec_object_incref(nd->data);
}
if (nd->nodes != NULL)
{
- IMAP_2slist_ref(nd, slist);
+ IMAP_2vec_ref(nd, vec);
}
}
}
/* this must be the same object */
assert (node_nd->data == dest_nd->data);
/* we are sure there is a ref left */
- slist_object_decref(node_nd->data);
+ vec_object_decref(node_nd->data);
}
else
{
/* this must be the same object */
assert (node_nd->data == dest_nd->data);
/* we are sure to have one ref left */
- slist_object_decref(dest_nd->data);
+ vec_object_decref(dest_nd->data);
dest_nd->data = NULL;
dest->size--;
assert (node_nd->data == dest_nd->data);
/* we are sure to have one ref left */
- slist_object_decref(dest_nd->data);
+ vec_object_decref(dest_nd->data);
/* but now we are not sure anymore */
(*decref_cb)(node_nd->data);
/*
- * iso8601.c - Library to parse ISO 8601 dates
- *
- * Note: time-zones are found with tzset() in either /usr/lib/zoneinfo/ or
- * /usr/share/zoneinfo/
- *
- * (This library is Linux only)
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 21-04-2016
- *
+ * iso8601.c - Library to parse ISO 8601 dates. Time-zones are found with
+ * tzset() in either /usr/lib/zoneinfo/ or /usr/share/zoneinfo/.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
/*
- * llist.c - Linked List
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 03-05-2016
- *
+ * llist.c - Linked List implementation.
*/
-
#include <stddef.h>
#include <stdlib.h>
#include <llist/llist.h>
* Copy the linked list to a simple list.
* (returns NULL in case an error has occurred)
*/
-slist_t * llist2slist(llist_t * llist)
+vec_t * llist2vec(llist_t * llist)
{
- slist_t * slist = slist_new(llist->len);
+ vec_t * vec = vec_new(llist->len);
- if (slist == NULL)
+ if (vec == NULL)
{
return NULL;
}
for (n = 0; node != NULL; n++, node = node->next)
{
- slist->data[n] = node->data;
+ vec->data[n] = node->data;
}
- slist->len = n;
+ vec->len = n;
- return slist;
+ return vec;
}
/*
/*
- * lock.c - SiriDB Lock.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * This module works only in Linux
- *
- * changes
- * - initial version, 13-07-2016
- *
+ * lock.c - Lock a directory by using a lock file.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
/*
- * logger.c - log module
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-03-2016
- *
+ * logger.h - Logging module.
*/
#include <logger/logger.h>
#include <stdio.h>
/*
* owcrypt.c - One Way Encryption. (used for storing a database user password)
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2017, Transceptor Technology
- *
- * changes:
- * - initial version, 24-02-2017
- *
* purpose:
* - provide an encryption algorithm to prevent password guessing.
* - passwords should be stored using one way encryption so the original
switch (salt[OWCRYPT_SALT_SZ - 1])
{
case '0':
+ /* deprecated version */
owcrypt0(password, salt, encrypted);
break;
case '1':
}
}
+/* deprecated */
static void owcrypt0(
const char * password,
const char * salt,
* http://stackoverflow.com/questions/63166/how-to-determine-cpu-and-
* memory-consumption-from-inside-a-process
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 18-03-2016
- *
*/
#include <stdlib.h>
/*
- * qpack.c - efficient binary serialization format
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 11-03-2016
- * ((l + n) // 4 + 1) * 4
+ * qpack.c - Efficient binary serialization format.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
+++ /dev/null
-/*
- * account.c - SiriDB Administrative User.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2017, Transceptor Technology
- *
- * changes
- * - initial version, 16-03-2017
- *
- */
-#include <siri/admin/account.h>
-#include <stddef.h>
-#include <owcrypt/owcrypt.h>
-#include <xpath/xpath.h>
-#include <siri/siri.h>
-#include <stdarg.h>
-#include <logger/logger.h>
-
-#define SIRI_ADMIN_ACCOUNT_SCHEMA 1
-#define FILENAME ".accounts.dat"
-
-#define DEFAULT_ACCOUNT "sa"
-#define DEFAULT_PASSWORD "siri"
-
-static int ACCOUNT_free(siri_admin_account_t * account, void * args);
-static int ACCOUNT_save(siri_admin_account_t * account, qp_fpacker_t * fpacker);
-static void ACCOUNT_msg(char * err_msg, char * fmt, ...);
-static int ACCOUNT_cmp(
- siri_admin_account_t * account,
- qp_obj_t * qp_account);
-
-/*
- * Initialize siri->accounts. Returns 0 if successful or -1 in case of an error
- * (a signal might be raised because of qpack)
- */
-int siri_admin_account_init(siri_t * siri)
-{
- qp_unpacker_t * unpacker;
- qp_obj_t qp_schema;
- qp_obj_t qp_account;
- qp_obj_t qp_password;
- int rc = 0;
-
- /* get service accounts file name */
- char fn[strlen(siri->cfg->default_db_path) + strlen(FILENAME) + 1];
-
- /* initialize linked list */
- siri->accounts = llist_new();
- if (siri->accounts == NULL)
- {
- return -1;
- }
-
- /* make filename */
- sprintf(fn, "%s%s", siri->cfg->default_db_path, FILENAME);
-
- if (!xpath_file_exist(fn))
- {
- /* missing file, lets create the first account */
- qp_account.via.raw = (unsigned char *) DEFAULT_ACCOUNT;
- qp_account.len = 4;
- qp_password.via.raw = (unsigned char *) DEFAULT_PASSWORD;
- qp_password.len = 4;
-
- return (siri_admin_account_new(
- siri,
- &qp_account,
- &qp_password,
- 0,
- NULL) || siri_admin_account_save(siri, NULL));
- }
-
- if ((unpacker = qp_unpacker_ff(fn)) == NULL)
- {
- return -1; /* a signal is raised is case of a memory error */
- }
-
- if ( !qp_is_array(qp_next(unpacker, NULL)) ||
- qp_next(unpacker, &qp_schema) != QP_INT64 ||
- qp_schema.via.int64 != SIRI_ADMIN_ACCOUNT_SCHEMA)
- {
- log_critical("Invalid schema detected in '%s'", fn);
- qp_unpacker_ff_free(unpacker);
- return -1;
- }
-
- while ( rc == 0 &&
- qp_is_array(qp_next(unpacker, NULL)) &&
- qp_next(unpacker, &qp_account) == QP_RAW &&
- qp_next(unpacker, &qp_password) == QP_RAW &&
- qp_password.len > 12) /* old and new passwords are > 12 */
- {
- rc = siri_admin_account_new(siri, &qp_account, &qp_password, 1, NULL);
- }
-
- qp_unpacker_ff_free(unpacker);
- return rc;
-}
-
-/*
- * Creates a new service account and returns 0 if successful. In case of
- * an error, -1 is returned, err_msg is set.
- *
- * When successful, the account is added to the siri->accounts linked list.
- *
- * is_encrypted should be zero if the password is not encrypted yet.
- *
- * Note: the account will not be saved to disk. Call siri_admin_account_save()
- * to save a new service account.
- */
-int siri_admin_account_new(
- siri_t * siri,
- qp_obj_t * qp_account,
- qp_obj_t * qp_password,
- int is_encrypted,
- char * err_msg)
-{
- siri_admin_account_t * account;
-
- account = (siri_admin_account_t *) llist_get(
- siri->accounts,
- (llist_cb) ACCOUNT_cmp,
- (void *) qp_account);
-
- if (account != NULL)
- {
- ACCOUNT_msg(
- err_msg,
- "service account '%.*s' already exists",
- (int) qp_account->len,
- qp_account->via.raw);
- return -1;
- }
-
- if (qp_account->len < 2)
- {
- ACCOUNT_msg(
- err_msg,
- "service account name should have at least 2 characters");
- return -1;
- }
-
- if (qp_password->len < 2)
- {
- ACCOUNT_msg(
- err_msg,
- "service account password should have at least 2 characters");
- return -1;
- }
-
- account = (siri_admin_account_t *) malloc(sizeof(siri_admin_account_t));
- if (account == NULL)
- {
- ACCOUNT_msg(err_msg, "memory allocation error");
- return -1;
- }
-
- account->account = strndup(
- (const char *) qp_account->via.raw, qp_account->len);
- account->password = strndup(
- (const char *) qp_password->via.raw, qp_password->len);
-
- if (!is_encrypted && account->password != NULL)
- {
- char encrypted[OWCRYPT_SZ];
- char salt[OWCRYPT_SALT_SZ];
-
- /* generate a random salt */
- owcrypt_gen_salt(salt);
-
- /* encrypt the accounts password */
- owcrypt(account->password, salt, encrypted);
-
- /* replace with encrypted password */
- free(account->password);
- account->password = strdup(encrypted);
- }
-
- if ( account->account == NULL ||
- account->password == NULL ||
- llist_append(siri->accounts, account))
- {
- ACCOUNT_msg(err_msg, "memory allocation error");
- return -1;
- }
- return 0;
-}
-
-/*
- * Returns 0 if the account/password is valid or another value if not.
- */
-int siri_admin_account_check(
- siri_t * siri,
- qp_obj_t * qp_account,
- qp_obj_t * qp_password,
- char * err_msg)
-{
- siri_admin_account_t * account;
- char pw[OWCRYPT_SZ];
- char * password;
-
- account = (siri_admin_account_t *) llist_get(
- siri->accounts,
- (llist_cb) ACCOUNT_cmp,
- (void *) qp_account);
-
- if (account == NULL)
- {
- ACCOUNT_msg(
- err_msg,
- "cannot find service account '%.*s'",
- (int) qp_account->len,
- qp_account->via.raw);
- return -1;
- }
-
- password= strndup(
- (const char *) qp_password->via.raw, qp_password->len);
-
- if (password == NULL)
- {
- ACCOUNT_msg(err_msg, "memory allocation error");
- return -1;
- }
-
- owcrypt(password, account->password, pw);
- free(password);
-
- if (strcmp(pw, account->password))
- {
- ACCOUNT_msg(
- err_msg,
- "incorrect password for service account '%.*s'",
- (int) qp_account->len,
- qp_account->via.raw);
- return -1;
- }
-
- return 0;
-}
-
-/*
- * Returns 0 if the password is successful changed or -1 if not.
- *
- * Note: the password change is not saved, call siri_admin_account_save().
- */
-int siri_admin_account_change_password(
- siri_t * siri,
- qp_obj_t * qp_account,
- qp_obj_t * qp_password,
- char * err_msg)
-{
- siri_admin_account_t * account;
- char encrypted[OWCRYPT_SZ];
- char salt[OWCRYPT_SALT_SZ];
- char * password;
-
- account = (siri_admin_account_t *) llist_get(
- siri->accounts,
- (llist_cb) ACCOUNT_cmp,
- (void *) qp_account);
-
- if (account == NULL)
- {
- ACCOUNT_msg(
- err_msg,
- "cannot find service account '%.*s'",
- (int) qp_account->len,
- qp_account->via.raw);
- return -1;
- }
-
- password= strndup(
- (const char *) qp_password->via.raw, qp_password->len);
-
- if (password == NULL)
- {
- ACCOUNT_msg(err_msg, "memory allocation error");
- return -1;
- }
-
- /* generate a random salt */
- owcrypt_gen_salt(salt);
-
- /* encrypt the accounts password */
- owcrypt(password, salt, encrypted);
-
- free(password);
-
- password = strdup(encrypted);
- if (password == NULL)
- {
- ACCOUNT_msg(err_msg, "memory allocation error");
- return -1;
- }
-
- /* replace account password with new encrypted password */
- free(account->password);
- account->password = password;
-
- return 0;
-}
-
-/*
- * Returns 0 if dropped or -1 in case the account was not found.
- *
- * Note: accounts are not saved, call siri_admin_account_save().
- */
-int siri_admin_account_drop(
- siri_t * siri,
- qp_obj_t * qp_account,
- char * err_msg)
-{
- siri_admin_account_t * account;
- account = (siri_admin_account_t *) llist_remove(
- siri->accounts,
- (llist_cb) ACCOUNT_cmp,
- (void *) qp_account);
- if (account == NULL)
- {
- ACCOUNT_msg(
- err_msg,
- "cannot find service account '%.*s'",
- (int) qp_account->len,
- qp_account->via.raw);
- return -1;
- }
-
- ACCOUNT_free(account, NULL);
- return 0;
-}
-
-/*
- * Destroy service accounts. siri->accounts is allowed to be NULL.
- */
-void siri_admin_account_destroy(siri_t * siri)
-{
- if (siri->accounts != NULL)
- {
- llist_free_cb(siri->accounts, (llist_cb) ACCOUNT_free, NULL);
- }
-}
-
-/*
- * Returns 0 if successful or EOF if not.
- */
-int siri_admin_account_save(siri_t * siri, char * err_msg)
-{
- qp_fpacker_t * fpacker;
-
- /* get service accounts file name */
- char fn[strlen(siri->cfg->default_db_path) + strlen(FILENAME) + 1];
-
- /* make filename */
- sprintf(fn, "%s%s", siri->cfg->default_db_path, FILENAME);
-
- if (
- /* open a new account file */
- (fpacker = qp_open(fn, "w")) == NULL ||
-
- /* open a new array */
- qp_fadd_type(fpacker, QP_ARRAY_OPEN) ||
-
- /* write the current schema */
- qp_fadd_int16(fpacker, SIRI_ADMIN_ACCOUNT_SCHEMA) ||
-
- /* we can and should skip this if we have no accounts to save */
- llist_walk(siri->accounts, (llist_cb) ACCOUNT_save, fpacker) ||
-
- /* close file pointer */
- qp_close(fpacker))
- {
- ACCOUNT_msg(err_msg, "error saving service accounts");
- return EOF;
- }
- return 0;
-}
-
-/*
- * Destroy an account.
- */
-static int ACCOUNT_free(
- siri_admin_account_t * account,
- void * args __attribute__((unused)))
-{
- free(account->account);
- free(account->password);
- free(account);
- return 0;
-}
-
-/*
- * Returns 0 if successful and -1 in case an error occurred.
- */
-static int ACCOUNT_save(siri_admin_account_t * account, qp_fpacker_t * fpacker)
-{
- int rc = 0;
-
- rc += qp_fadd_type(fpacker, QP_ARRAY2);
- rc += qp_fadd_string(fpacker, account->account);
- rc += qp_fadd_string(fpacker, account->password);
-
- return rc;
-}
-
-static void ACCOUNT_msg(char * err_msg, char * fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- if (err_msg != NULL)
- {
- vsnprintf(err_msg, SIRI_MAX_SIZE_ERR_MSG, fmt, args);
- }
- else
- {
- log_error(fmt, args);
- }
- va_end(args);
-}
-
-static int ACCOUNT_cmp(
- siri_admin_account_t * account,
- qp_obj_t * qp_account)
-{
- size_t len = strlen(account->account);
- return (len == qp_account->len && strncmp(
- account->account,
- (const char *) qp_account->via.raw,
- len) == 0);
-}
+++ /dev/null
-/*
- * client.c - Client for expanding a siridb database.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2017, Transceptor Technology
- *
- * changes
- * - initial version, 24-03-2017
- *
- */
-#include <string.h>
-#include <stdarg.h>
-#include <lock/lock.h>
-#include <logger/logger.h>
-#include <siri/siri.h>
-#include <siri/version.h>
-#include <siri/admin/client.h>
-#include <siri/admin/request.h>
-#include <siri/net/stream.h>
-#include <siri/net/protocol.h>
-#include <siri/net/tcp.h>
-#include <siri/db/server.h>
-
-/* 15 seconds */
-#define CLIENT_REQUEST_TIMEOUT 15000
-#define CLIENT_FLAGS_TIMEOUT 1
-#define CLIENT_FLAGS_NO_ROLLBACK 2
-#define MAX_VERSION_LEN 256
-
-enum
-{
- CLIENT_REQUEST_INIT,
- CLIENT_REQUEST_STATUS,
- CLIENT_REQUEST_POOLS,
- CLIENT_REQUEST_FILE_USERS,
- CLIENT_REQUEST_FILE_GROUPS,
- CLIENT_REQUEST_FILE_SERVERS,
- CLIENT_REQUEST_FILE_DATABASE,
- CLIENT_REQUEST_REGISTER_SERVER
-};
-
-static void CLIENT_write_cb(uv_write_t * req, int status);
-static void CLIENT_on_connect(uv_connect_t * req, int status);
-static void CLIENT_on_data(sirinet_stream_t * client, sirinet_pkg_t * pkg);
-static void CLIENT_request_timeout(uv_timer_t * handle);
-static void CLIENT_on_auth_success(siri_admin_client_t * adm_client);
-static int CLIENT_resolve_dns(
- siri_admin_client_t * adm_client,
- int ai_family,
- char * err_msg);
-static void CLIENT_on_resolved(
- uv_getaddrinfo_t * resolver,
- int status,
- struct addrinfo * res);
-static void CLIENT_err(
- siri_admin_client_t * adm_client,
- const char * fmt,
- ...);
-static void CLIENT_send_pkg(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg);
-static void CLIENT_on_error_msg(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg);
-static void CLIENT_on_register_server(siri_admin_client_t * adm_client);
-static void CLIENT_on_file_database(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg);
-static void CLIENT_on_file_servers(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg);
-static void CLIENT_on_file_groups(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg);
-static void CLIENT_on_file_users(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg);
-static void CLIENT_on_request_pools(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg);
-static void CLIENT_on_request_status(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg);
-
-/*
- * Initializes a request for a new pool or replica and returns 0 when
- * successful. In case of an error, err_msg will be set and a value other than
- * 0 is returned. (a signal can be raised.) When successful and only when
- * successful, a response will be send to the provided client using the given
- * pid.
- */
-int siri_admin_client_request(
- uint16_t pid,
- uint16_t port,
- int pool,
- uuid_t * uuid,
- qp_obj_t * host,
- qp_obj_t * username,
- qp_obj_t * password,
- qp_obj_t * dbname,
- const char * dbpath,
- sirinet_stream_t * client,
- char * err_msg)
-{
- siri_admin_client_t * adm_client;
- struct in_addr sa;
- struct in6_addr sa6;
-
- if (siri.client != NULL)
- {
- sprintf(err_msg, "manage socket already in use");
- return -1;
- }
-
- siri.client = sirinet_stream_new(STREAM_TCP_MANAGE, &CLIENT_on_data);
- if (siri.client == NULL)
- {
- sprintf(err_msg, "memory allocation error");
- return -1;
- }
-
- uv_tcp_init(siri.loop, (uv_tcp_t *) siri.client->stream);
-
- adm_client = (siri_admin_client_t *) malloc(sizeof(siri_admin_client_t));
- if (adm_client == NULL)
- {
- sirinet_stream_decref(siri.client);
- sprintf(err_msg, "memory allocation error");
- return -1;
- }
- adm_client->pid = pid;
- adm_client->port = port;
- adm_client->host = strndup(
- (const char *) host->via.raw, host->len);
- adm_client->username = strndup(
- (const char *) username->via.raw, username->len);
- adm_client->password = strndup(
- (const char *) password->via.raw, password->len);
- adm_client->dbname = strndup(
- (const char *) dbname->via.raw, dbname->len);
- adm_client->dbpath = strdup(dbpath);
- adm_client->client = client;
- adm_client->request = CLIENT_REQUEST_INIT;
- adm_client->flags = 0;
- adm_client->pool = pool;
- memcpy(&adm_client->uuid, uuid, 16);
-
-
- siri.client->origin = (void *) adm_client;
-
- sirinet_stream_incref(adm_client->client);
-
- if (adm_client->host == NULL ||
- adm_client->username == NULL ||
- adm_client->password == NULL ||
- adm_client->dbname == NULL ||
- adm_client->dbpath == NULL)
- {
- sirinet_stream_decref(siri.client);
- sprintf(err_msg, "memory allocation error");
- return -1;
- }
-
- if (inet_pton(AF_INET, adm_client->host, &sa))
- {
- /* IPv4 */
- struct sockaddr_in dest;
-
- uv_connect_t * req = (uv_connect_t *) malloc(sizeof(uv_connect_t));
- if (req == NULL)
- {
- sirinet_stream_decref(siri.client);
- sprintf(err_msg, "memory allocation error");
- return -1;
- }
- log_debug(
- "Trying to connect to '%s:%u'...",
- adm_client->host,
- adm_client->port);
-
- uv_ip4_addr(adm_client->host, adm_client->port, &dest);
- uv_tcp_connect(
- req,
- (uv_tcp_t *) siri.client->stream,
- (const struct sockaddr *) &dest,
- CLIENT_on_connect);
- }
- else if (inet_pton(AF_INET6, adm_client->host, &sa6))
- {
- /* IPv6 */
- struct sockaddr_in6 dest6;
-
- uv_connect_t * req = (uv_connect_t *) malloc(sizeof(uv_connect_t));
- if (req == NULL)
- {
- sirinet_stream_decref(siri.client);
- sprintf(err_msg, "memory allocation error");
- return -1;
- }
- log_debug(
- "Trying to connect to '%s:%u'...",
- adm_client->host,
- adm_client->port);
- uv_ip6_addr(adm_client->host, adm_client->port, &dest6);
- uv_tcp_connect(
- req,
- (uv_tcp_t *) siri.client->stream,
- (const struct sockaddr *) &dest6,
- CLIENT_on_connect);
- }
- else
- {
- if (CLIENT_resolve_dns(
- adm_client,
- dns_req_family_map[siri.cfg->ip_support],
- err_msg))
- {
- sirinet_stream_decref(siri.client);
- return -1; /* err_msg is set */
- }
- }
- uv_timer_init(siri.loop, &siri.timer);
- return 0;
-}
-
-/*
- * Destroy the client request. (will be called when the socket is destroyed)
- */
-void siri_admin_client_free(siri_admin_client_t * adm_client)
-{
- if (adm_client != NULL)
- {
- sirinet_stream_decref(adm_client->client);
- free(adm_client->host);
- free(adm_client->username);
- free(adm_client->password);
- free(adm_client->dbname);
- free(adm_client->dbpath);
- free(adm_client);
- }
-}
-/*
- * Try to get an ip address from dns.
- *
- * This function should return 0 when we can start an attempt for discovering
- * dns. When the result is not zero, CLIENT_on_resolved will not be called and
- * err_msg is set.
- */
-static int CLIENT_resolve_dns(
- siri_admin_client_t * adm_client,
- int ai_family,
- char * err_msg)
-{
- struct addrinfo hints;
- hints.ai_family = ai_family;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- hints.ai_flags = AI_NUMERICSERV;
-
- uv_getaddrinfo_t * resolver =
- (uv_getaddrinfo_t *) malloc(sizeof(uv_getaddrinfo_t));
-
- if (resolver == NULL)
- {
- sprintf(err_msg, "memory allocation error");
- return -1;
- }
-
- int result;
- resolver->data = adm_client;
-
- char port[6]= {'\0'};
- sprintf(port, "%u", adm_client->port);
-
- result = uv_getaddrinfo(
- siri.loop,
- resolver,
- (uv_getaddrinfo_cb) CLIENT_on_resolved,
- adm_client->host,
- port,
- &hints);
-
- if (result)
- {
- snprintf(
- err_msg,
- SIRI_MAX_SIZE_ERR_MSG,
- "getaddrinfo call error %s",
- uv_err_name(result));
- free(resolver);
- }
-
- return result;
-}
-
-/*
- * Callback used to check if resolving an ip address was successful.
- */
-static void CLIENT_on_resolved(
- uv_getaddrinfo_t * resolver,
- int status,
- struct addrinfo * res)
-{
- siri_admin_client_t * adm_client = (siri_admin_client_t *) resolver->data;
-
- if (status < 0)
- {
- CLIENT_err(
- adm_client,
- "cannot resolve ip address for '%s' (error: %s)",
- adm_client->host,
- uv_err_name(status));
- }
- else
- {
- uv_connect_t * req = (uv_connect_t *) malloc(sizeof(uv_connect_t));
- if (req == NULL)
- {
- CLIENT_err(adm_client, "memory allocation error");
- }
- else
- {
- uv_tcp_connect(
- req,
- (uv_tcp_t *) siri.client->stream,
- (const struct sockaddr *) res->ai_addr,
- CLIENT_on_connect);
- }
- }
-
- uv_freeaddrinfo(res);
- free(resolver);
-}
-
-/*
- * In case a client request fails, this function should be called to end
- * the request. A package with the error message will be send to the client.
- */
-static void CLIENT_err(
- siri_admin_client_t * adm_client,
- const char * fmt,
- ...)
-{
- char err_msg[SIRI_MAX_SIZE_ERR_MSG];
-
- va_list args;
- va_start(args, fmt);
- vsnprintf(err_msg, SIRI_MAX_SIZE_ERR_MSG, fmt, args);
- va_end(args);
-
- sirinet_pkg_t * package = sirinet_pkg_err(
- adm_client->pid,
- strlen(err_msg),
- CPROTO_ERR_ADMIN,
- err_msg);
-
- if (package != NULL)
- {
- sirinet_pkg_send(adm_client->client, package);
- }
-
- log_error(err_msg);
-
- if (~adm_client->flags & CLIENT_FLAGS_NO_ROLLBACK)
- {
- siri_admin_request_rollback(adm_client->dbpath);
- }
-
- sirinet_stream_decref(siri.client);
-
- uv_close((uv_handle_t *) &siri.timer, NULL);
-}
-
-/*
- * Send a package to the 'other' SiriDB server. This function can be used for
- * sending api requests for all database information required to create the
- * database. Note that all packages are send with the same pid so packages
- * should be send in sequence, not parallel.
- *
- * Note: pkg will be freed by calling this function.
- */
-static void CLIENT_send_pkg(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg)
-{
- uv_write_t * req = (uv_write_t *) malloc(sizeof(uv_write_t));
- if (req == NULL)
- {
- free(pkg);
- CLIENT_err(adm_client, "memory allocation error");
- }
- req->data = adm_client;
-
- adm_client->pkg = pkg;
-
- /* set the correct check bit */
- pkg->checkbit = pkg->tp ^ 255;
-
- uv_timer_start(
- &siri.timer,
- CLIENT_request_timeout,
- CLIENT_REQUEST_TIMEOUT,
- 0);
-
- siri.timer.data = adm_client;
-
- uv_buf_t wrbuf = uv_buf_init(
- (char *) pkg,
- sizeof(sirinet_pkg_t) + pkg->len);
-
- uv_write(
- req,
- siri.client->stream,
- &wrbuf,
- 1,
- CLIENT_write_cb);
-}
-
-/*
- * Write call-back.
- */
-static void CLIENT_write_cb(uv_write_t * req, int status)
-{
- siri_admin_client_t * adm_client = (siri_admin_client_t *) req->data;
-
- if (status)
- {
- uv_timer_stop(&siri.timer);
- CLIENT_err(adm_client, "socket write error: %s", uv_strerror(status));
- }
-
- free(adm_client->pkg);
- free(req);
-}
-
-/*
- * Called when a connection to the 'other' siridb server is made.
- * An authentication request will be send by user/password since this will be
- * using the client connection. (a signal can be raised)
- */
-static void CLIENT_on_connect(uv_connect_t * req, int status)
-{
- sirinet_stream_t * client = req->handle->data;
- siri_admin_client_t * adm_client = client->origin;
-
- if (status == 0)
- {
- log_debug(
- "Connected to SiriDB server: '%s:%u', "
- "sending authentication request",
- adm_client->host, adm_client->port);
-
- uv_read_start(
- req->handle,
- sirinet_stream_alloc_buffer,
- sirinet_stream_on_data);
-
- sirinet_pkg_t * pkg;
- qp_packer_t * packer = sirinet_packer_new(512);
-
- if (packer == NULL)
- {
- CLIENT_err(adm_client, "memory allocation error");
- }
- else
- {
- if (qp_add_type(packer, QP_ARRAY3) ||
- qp_add_string(packer, adm_client->username) ||
- qp_add_string(packer, adm_client->password) ||
- qp_add_string(packer, adm_client->dbname))
- {
- qp_packer_free(packer);
- }
- else
- {
- pkg = sirinet_packer2pkg(packer, 0, CPROTO_REQ_AUTH);
- CLIENT_send_pkg(adm_client, pkg);
- }
-
- }
- }
- else
- {
- CLIENT_err(
- adm_client,
- "connecting to server '%s:%u' failed with error: %s",
- adm_client->host,
- adm_client->port,
- uv_strerror(status));
- }
- free(req);
-}
-
-/*
- * on-data call-back function.
- */
-static void CLIENT_on_data(sirinet_stream_t * client, sirinet_pkg_t * pkg)
-{
- siri_admin_client_t * adm_client = client->origin;
- log_debug(
- "Client response received (pid: %" PRIu16
- ", len: %" PRIu32 ", tp: %s)",
- pkg->pid,
- pkg->len,
- sirinet_cproto_server_str(pkg->tp));
-
- if (adm_client->flags & CLIENT_FLAGS_TIMEOUT)
- {
- log_error("Client response received which was timed-out earlier");
- }
- else
- {
- uv_timer_stop(&siri.timer);
-
- switch ((cproto_server_t) pkg->tp)
- {
- case CPROTO_RES_AUTH_SUCCESS:
- CLIENT_on_auth_success(adm_client);
- break;
- case CPROTO_RES_QUERY:
- switch (adm_client->request)
- {
- case CLIENT_REQUEST_STATUS:
- CLIENT_on_request_status(adm_client, pkg);
- break;
- case CLIENT_REQUEST_POOLS:
- CLIENT_on_request_pools(adm_client, pkg);
- break;
- default:
- CLIENT_err(adm_client, "unexpected query response");
- }
- break;
- case CPROTO_RES_FILE:
- switch (adm_client->request)
- {
- case CLIENT_REQUEST_FILE_USERS:
- CLIENT_on_file_users(adm_client, pkg);
- break;
- case CLIENT_REQUEST_FILE_GROUPS:
- CLIENT_on_file_groups(adm_client, pkg);
- break;
- case CLIENT_REQUEST_FILE_SERVERS:
- CLIENT_on_file_servers(adm_client, pkg);
- break;
- case CLIENT_REQUEST_FILE_DATABASE:
- CLIENT_on_file_database(adm_client, pkg);
- break;
- default:
- CLIENT_err(adm_client, "unexpected query response");
- }
- break;
- case CPROTO_RES_ACK:
- switch (adm_client->request)
- {
- case CLIENT_REQUEST_REGISTER_SERVER:
- CLIENT_on_register_server(adm_client);
- break;
- default:
- CLIENT_err(adm_client, "unexpected query response");
- }
- break;
- case CPROTO_ERR_AUTH_CREDENTIALS:
- CLIENT_err(
- adm_client,
- "invalid credentials for database '%s' on server '%s:%u'",
- adm_client->dbname,
- adm_client->host,
- adm_client->port);
- break;
- case CPROTO_ERR_AUTH_UNKNOWN_DB:
- CLIENT_err(
- adm_client,
- "database '%s' does not exist on server '%s:%u'",
- adm_client->dbname,
- adm_client->host,
- adm_client->port);
- break;
- case CPROTO_ERR_MSG:
- case CPROTO_ERR_QUERY:
- case CPROTO_ERR_INSERT:
- case CPROTO_ERR_SERVER:
- case CPROTO_ERR_POOL:
- case CPROTO_ERR_USER_ACCESS:
- CLIENT_on_error_msg(adm_client, pkg);
- break;
- default:
- CLIENT_err(
- adm_client,
- "unexpected response (%u) received from server '%s:%u'",
- pkg->tp,
- adm_client->host,
- adm_client->port);
- }
- }
-}
-
-/*
- * Called when register server was successful.
- */
-static void CLIENT_on_register_server(siri_admin_client_t * adm_client)
-{
- sirinet_pkg_t * package = sirinet_pkg_new(
- adm_client->pid,
- 0,
- CPROTO_ACK_ADMIN,
- NULL);
-
- if (package != NULL)
- {
- sirinet_pkg_send(adm_client->client, package);
- }
-
- log_info(
- "Finished registering server on database '%s'",
- adm_client->dbname);
-
- sirinet_stream_decref(siri.client);
- uv_close((uv_handle_t *) &siri.timer, NULL);
-}
-
-/*
- * Called when database.dat is received.
- */
-static void CLIENT_on_file_database(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg)
-{
- FILE * fp;
- qp_unpacker_t unpacker;
- qp_obj_t qp_uuid;
- siridb_t * siridb;
- int rc;
- /* 13 = strlen("database.dat")+1 */
- char fn[strlen(adm_client->dbpath) + 13];
- sprintf(fn, "%sdatabase.dat", adm_client->dbpath);
-
- qp_unpacker_init(&unpacker, pkg->data, pkg->len);
-
- if (qp_is_array(qp_next(&unpacker, NULL)) &&
- /* schema check is not required at this moment but can be done here */
- qp_next(&unpacker, NULL) == QP_INT64 &&
- qp_next(&unpacker, &qp_uuid) == QP_RAW &&
- qp_uuid.len == 16)
- {
- memcpy(unpacker.pt - 16, &adm_client->uuid, 16);
- }
- else
- {
- CLIENT_err(adm_client, "invalid database file received");
- return;
- }
-
- fp = fopen(fn, "w");
-
- if (fp == NULL)
- {
- CLIENT_err(adm_client, "cannot write or create file: %s", fn);
- return;
- }
-
- rc = fwrite(pkg->data, pkg->len, 1, fp);
-
- if (fclose(fp) || rc != 1)
- {
- CLIENT_err(adm_client, "cannot write or create file: %s", fn);
- return;
- }
-
- siridb = siridb_new(adm_client->dbpath, LOCK_QUIT_IF_EXIST);
-
- if (siridb == NULL)
- {
- CLIENT_err(adm_client, "error loading database");
- return;
- }
-
- /* roll-back is not possible anymore */
- adm_client->flags |= CLIENT_FLAGS_NO_ROLLBACK;
-
- siridb->server->flags |= SERVER_FLAG_RUNNING;
-
- /* Force one heart-beat */
- siri_heartbeat_force();
-
- sirinet_pkg_t * package;
- qp_packer_t * packer = sirinet_packer_new(512);
-
- if (packer == NULL)
- {
- CLIENT_err(adm_client, "memory allocation error");
- return;
- }
-
- adm_client->request = CLIENT_REQUEST_REGISTER_SERVER;
-
- if (qp_add_type(packer, QP_ARRAY4) ||
- qp_add_raw(packer, (const unsigned char *) &adm_client->uuid, 16) ||
- qp_add_string(packer, siri.cfg->server_address) ||
- qp_add_int32(packer, (int32_t) siri.cfg->listen_backend_port) ||
- qp_add_int32(packer, (int32_t) adm_client->pool))
- {
- qp_packer_free(packer);
- CLIENT_err(adm_client, "memory allocation error");
- return;
- }
-
- package = sirinet_packer2pkg(packer, 0, CPROTO_REQ_REGISTER_SERVER);
- CLIENT_send_pkg(adm_client, package);
-}
-
-/*
- * Called when servers.dat is received.
- */
-static void CLIENT_on_file_servers(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg)
-{
- FILE * fp;
- qp_unpacker_t unpacker;
- qp_types_t tp;
- int rc, n, close_num;
- /* 12 = strlen("servers.dat") + 1 */
- char fn[strlen(adm_client->dbpath) + 12];
- sprintf(fn, "%sservers.dat", adm_client->dbpath);
-
- fp = fopen(fn, "w");
- if (fp == NULL)
- {
- CLIENT_err(adm_client, "cannot write or create file: %s", fn);
- return;
- }
-
- qp_unpacker_init(&unpacker, pkg->data, pkg->len);
- tp = qp_next(&unpacker, NULL);
- if (tp >= QP_ARRAY0 && tp <= QP_ARRAY5)
- {
- pkg->data[0] = QP_ARRAY_OPEN;
- }
- else if (tp != QP_ARRAY_OPEN)
- {
- CLIENT_err(adm_client, "invalid server status response");
- return;
- }
-
- /* schema checking is not required at this moment but can be done here */
- qp_next(&unpacker, NULL);
-
- tp = qp_next(&unpacker, NULL);
-
- if (!qp_is_array(tp))
- {
- CLIENT_err(adm_client, "invalid server status response");
- return;
- }
-
- close_num = (tp == QP_ARRAY_OPEN) ? 1 : 0;
-
- /* trim closing */
- for (n = pkg->len;
- (unsigned char) pkg->data[n - 1] == QP_ARRAY_CLOSE;
- n--);
-
- rc = (fwrite(pkg->data, n, 1, fp) == 1) ? 0 : EOF;
-
- if (close_num)
- {
- rc += qp_fadd_type(fp, QP_ARRAY_CLOSE);
- }
-
- rc += qp_fadd_type(fp, QP_ARRAY4);
- rc += qp_fadd_raw(fp, (const unsigned char *) &adm_client->uuid, 16);
- rc += qp_fadd_string(fp, siri.cfg->server_address);
- rc += qp_fadd_int32(fp, (int32_t) siri.cfg->listen_backend_port);
- rc += qp_fadd_int32(fp, (int32_t) adm_client->pool);
- rc += fclose(fp);
-
- if (rc)
- {
- CLIENT_err(adm_client, "cannot write or create file: %s", fn);
- }
- else
- {
- sirinet_pkg_t * package;
- adm_client->request = CLIENT_REQUEST_FILE_DATABASE;
- package = sirinet_pkg_new(0, 0, CPROTO_REQ_FILE_DATABASE, NULL);
- if (package == NULL)
- {
- CLIENT_err(adm_client, "memory allocation error");
- }
- else
- {
- CLIENT_send_pkg(adm_client, package);
- }
- }
-}
-
-/*
- * Called when groups.dat is received.
- */
-static void CLIENT_on_file_groups(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg)
-{
- FILE * fp;
- /* 11 = strlen("groups.dat") + 1 */
- char fn[strlen(adm_client->dbpath) + 11];
- sprintf(fn, "%sgroups.dat", adm_client->dbpath);
-
- fp = fopen(fn, "w");
- if (fp == NULL)
- {
- CLIENT_err(adm_client, "cannot write or create file: %s", fn);
- }
- else
- {
- int rc = fwrite(pkg->data, pkg->len, 1, fp);
-
- if (fclose(fp) || rc != 1)
- {
- CLIENT_err(adm_client, "cannot write data to file: %s", fn);
- }
- else
- {
- adm_client->request = CLIENT_REQUEST_FILE_SERVERS;
- sirinet_pkg_t * package =
- sirinet_pkg_new(0, 0, CPROTO_REQ_FILE_SERVERS, NULL);
- if (package == NULL)
- {
- CLIENT_err(adm_client, "memory allocation error");
- }
- else
- {
- CLIENT_send_pkg(adm_client, package);
- }
- }
- }
-}
-
-/*
- * Called when users.dat is received.
- */
-static void CLIENT_on_file_users(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg)
-{
- FILE * fp;
- /* 10 = strlen("users.dat") + 1 */
- char fn[strlen(adm_client->dbpath) + 10];
- sprintf(fn, "%susers.dat", adm_client->dbpath);
-
- fp = fopen(fn, "w");
- if (fp == NULL)
- {
- CLIENT_err(adm_client, "cannot write or create file: %s", fn);
- }
- else
- {
- int rc = fwrite(pkg->data, pkg->len, 1, fp);
-
- if (fclose(fp) || rc != 1)
- {
- CLIENT_err(adm_client, "cannot write data to file: %s", fn);
- }
- else
- {
- adm_client->request = CLIENT_REQUEST_FILE_GROUPS;
- sirinet_pkg_t * package =
- sirinet_pkg_new(0, 0, CPROTO_REQ_FILE_GROUPS, NULL);
- if (package == NULL)
- {
- CLIENT_err(adm_client, "memory allocation error");
- }
- else
- {
- CLIENT_send_pkg(adm_client, package);
- }
- }
- }
-}
-
-/*
- * Called when 'list pools ...' response is received.
- * This function will check which pool number will be assigned for a new pool
- * or checks if a given pool for a new replica is valid.
- */
-static void CLIENT_on_request_pools(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg)
-{
- qp_unpacker_t unpacker;
- qp_unpacker_init(&unpacker, pkg->data, pkg->len);
- qp_obj_t qp_val;
- qp_obj_t qp_pool;
- qp_obj_t qp_servers;
- int columns_found = 0;
- int validate_pool = -1;
-
- if (!qp_is_map(qp_next(&unpacker, NULL)))
- {
- CLIENT_err(adm_client, "invalid server status response");
- return;
- }
-
- qp_next(&unpacker, &qp_val);
-
- while (qp_val.tp == QP_RAW)
- {
- if ( strncmp(
- (const char *) qp_val.via.raw,
- "columns",
- qp_val.len) == 0 &&
- qp_is_array(qp_next(&unpacker, NULL)) &&
- qp_next(&unpacker, &qp_val) == QP_RAW &&
- strncmp(
- (const char *) qp_val.via.raw, "pool", qp_val.len) == 0 &&
- qp_next(&unpacker, &qp_val) == QP_RAW &&
- strncmp(
- (const char *) qp_val.via.raw, "servers", qp_val.len) == 0)
- {
- if (qp_next(&unpacker, &qp_val) == QP_ARRAY_CLOSE)
- {
- qp_next(&unpacker, &qp_val);
- }
- columns_found = 1;
- continue;
- }
- if ( strncmp(
- (const char *) qp_val.via.raw, "pools", qp_val.len) == 0 &&
- qp_is_array(qp_next(&unpacker, NULL)))
- {
- qp_next(&unpacker, &qp_val);
-
- while (qp_is_array(qp_val.tp))
- {
- if (qp_next(&unpacker, &qp_pool) == QP_INT64 &&
- qp_next(&unpacker, &qp_servers) == QP_INT64)
- {
- if (adm_client->pool < 0)
- {
- /* looking for a new pool */
- if (qp_pool.via.int64 > validate_pool)
- {
- validate_pool = qp_pool.via.int64;
- }
- }
- else
- {
- if (qp_pool.via.int64 == adm_client->pool)
- {
- if (qp_servers.via.int64 > 1)
- {
- CLIENT_err(
- adm_client,
- "pool %d has already %" PRId64
- " servers",
- adm_client->pool,
- qp_servers.via.int64);
- return;
- }
- else
- {
- validate_pool = 0;
- }
- }
- }
- }
- else
- {
- CLIENT_err(adm_client, "invalid server status response");
- return;
- }
- if (qp_next(&unpacker, &qp_val) == QP_ARRAY_CLOSE)
- {
- qp_next(&unpacker, &qp_val);
- }
- }
- if (qp_val.tp == QP_ARRAY_CLOSE)
- {
- qp_next(&unpacker, &qp_val);
- }
- continue;
- }
-
- CLIENT_err(adm_client, "invalid server status response");
- return;
- }
-
- if (!columns_found)
- {
- CLIENT_err(adm_client, "invalid server status response");
- }
- else
- {
- sirinet_pkg_t * package;
-
- if (adm_client->pool < 0)
- {
- if (validate_pool == -1)
- {
- CLIENT_err(adm_client, "invalid server status response");
- return;
- }
- /* set new correct pool in case we request a new pool */
- adm_client->pool = validate_pool + 1;
- }
- else if (validate_pool == -1)
- {
- CLIENT_err(
- adm_client,
- "pool %d does not exist",
- adm_client->pool);
- return;
- }
-
- adm_client->request = CLIENT_REQUEST_FILE_USERS;
- package = sirinet_pkg_new(0, 0, CPROTO_REQ_FILE_USERS, NULL);
- if (package == NULL)
- {
- CLIENT_err(adm_client, "memory allocation error");
- }
- else
- {
- CLIENT_send_pkg(adm_client, package);
- }
- }
-}
-
-/*
- * Called when 'list servers ...' response is received.
- * This function will check if each current server has status running.
- * (this is a pre-check, the final register call does check for all servers
- * to have the running status once more)
- */
-static void CLIENT_on_request_status(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg)
-{
- qp_unpacker_t unpacker;
- qp_unpacker_init(&unpacker, pkg->data, pkg->len);
- qp_obj_t qp_val;
- qp_obj_t qp_name;
- qp_obj_t qp_status;
- qp_obj_t qp_version;
- int columns_found = 0;
- int servers_found = 0;
- char version[MAX_VERSION_LEN];
-
- if (!qp_is_map(qp_next(&unpacker, NULL)))
- {
- CLIENT_err(adm_client, "invalid server status response");
- return;
- }
-
- qp_next(&unpacker, &qp_val);
-
- while (qp_val.tp == QP_RAW)
- {
- if ( strncmp(
- (const char *) qp_val.via.raw,
- "columns",
- qp_val.len) == 0 &&
- qp_is_array(qp_next(&unpacker, NULL)) &&
- qp_next(&unpacker, &qp_val) == QP_RAW &&
- strncmp(
- (const char *) qp_val.via.raw, "name", qp_val.len) == 0 &&
- qp_next(&unpacker, &qp_val) == QP_RAW &&
- strncmp(
- (const char *) qp_val.via.raw,
- "status",
- qp_val.len) == 0 &&
- qp_next(&unpacker, &qp_val) == QP_RAW &&
- strncmp(
- (const char *) qp_val.via.raw, "version", qp_val.len) == 0)
- {
- if (qp_next(&unpacker, &qp_val) == QP_ARRAY_CLOSE)
- {
- qp_next(&unpacker, &qp_val);
- }
- columns_found = 1;
- continue;
- }
- if ( strncmp(
- (const char *) qp_val.via.raw,
- "servers",
- qp_val.len) == 0 &&
- qp_is_array(qp_next(&unpacker, NULL)))
- {
- qp_next(&unpacker, &qp_val);
-
- while (qp_is_array(qp_val.tp))
- {
- if (qp_next(&unpacker, &qp_name) == QP_RAW &&
- qp_next(&unpacker, &qp_status) == QP_RAW &&
- qp_next(&unpacker, &qp_version) == QP_RAW &&
- qp_version.len < MAX_VERSION_LEN)
- {
- /* copy and null terminate version */
- memcpy(version, qp_version.via.raw, qp_version.len);
- version[qp_version.len] = '\0';
-
- if (siri_version_cmp(version, SIRIDB_VERSION))
- {
- CLIENT_err(
- adm_client,
- "server '%.*s' is running on version %s "
- "while version %s is expected. (all SiriBD "
- "servers should run the same version)",
- (int) qp_name.len,
- qp_name.via.raw,
- version,
- SIRIDB_VERSION);
- return;
- }
-
- if (strncmp(
- (const char *) qp_status.via.raw,
- "running",
- qp_status.len) != 0)
- {
- CLIENT_err(
- adm_client,
- "server '%.*s' has status: '%.*s'",
- (int) qp_name.len,
- qp_name.via.raw,
- (int) qp_status.len,
- qp_status.via.raw);
- return;
- }
- servers_found++;
- }
- else
- {
- CLIENT_err(adm_client, "invalid server status response");
- return;
- }
- if (qp_next(&unpacker, &qp_val) == QP_ARRAY_CLOSE)
- {
- qp_next(&unpacker, &qp_val);
- }
- }
- if (qp_val.tp == QP_ARRAY_CLOSE)
- {
- qp_next(&unpacker, &qp_val);
- }
- continue;
- }
-
- CLIENT_err(adm_client, "invalid server status response");
- return;
- }
-
- if (!servers_found || !columns_found)
- {
- CLIENT_err(adm_client, "invalid server status response");
- }
- else
- {
- sirinet_pkg_t * package;
- qp_packer_t * packer = sirinet_packer_new(512);
- if (packer == NULL)
- {
- CLIENT_err(adm_client, "memory allocation error");
- }
- else
- {
- adm_client->request = CLIENT_REQUEST_POOLS;
-
- /* no need to check since this will always fit */
- qp_add_type(packer, QP_ARRAY1);
- qp_add_string(packer, "list pools pool, servers");
- package = sirinet_packer2pkg(packer, 0, CPROTO_REQ_QUERY);
- CLIENT_send_pkg(adm_client, package);
- }
- }
-}
-
-/*
- * Called when an error message is received.
- */
-static void CLIENT_on_error_msg(
- siri_admin_client_t * adm_client,
- sirinet_pkg_t * pkg)
-{
- qp_unpacker_t unpacker;
- qp_unpacker_init(&unpacker, pkg->data, pkg->len);
- qp_obj_t qp_err;
-
- if (qp_is_map(qp_next(&unpacker, NULL)) &&
- qp_next(&unpacker, NULL) == QP_RAW &&
- qp_next(&unpacker, &qp_err) == QP_RAW)
- {
- CLIENT_err(
- adm_client,
- "error on server '%s:%u': %.*s",
- adm_client->host,
- adm_client->port,
- (int) qp_err.len,
- qp_err.via.raw);
- }
- else
- {
- CLIENT_err(
- adm_client,
- "unexpected error on server '%s:%u'",
- adm_client->host,
- adm_client->port);
- }
-}
-
-/*
- * Called when authentication is successful.
- */
-static void CLIENT_on_auth_success(siri_admin_client_t * adm_client)
-{
- sirinet_pkg_t * pkg;
- qp_packer_t * packer = sirinet_packer_new(512);
- if (packer == NULL)
- {
- CLIENT_err(adm_client, "memory allocation error");
- }
- else
- {
- adm_client->request = CLIENT_REQUEST_STATUS;
-
- /* no need to check since this will always fit */
- qp_add_type(packer, QP_ARRAY1);
- qp_add_string(packer, "list servers name, status, version");
- pkg = sirinet_packer2pkg(packer, 0, CPROTO_REQ_QUERY);
- CLIENT_send_pkg(adm_client, pkg);
- }
-}
-
-/*
- * Timeout on a client request.
- */
-static void CLIENT_request_timeout(uv_timer_t * handle)
-{
- siri_admin_client_t * adm_client = (siri_admin_client_t *) handle->data;
-
- adm_client->flags |= CLIENT_FLAGS_TIMEOUT;
-
- CLIENT_err(adm_client, "request timeout");
-}
+++ /dev/null
-/*
- * request.c - SiriDB Administrative Request.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2017, Transceptor Technology
- *
- * changes
- * - initial version, 16-03-2017
- *
- */
-
-#define PCRE2_CODE_UNIT_WIDTH 8
-
-#include <siri/admin/account.h>
-#include <siri/admin/client.h>
-#include <stddef.h>
-#include <siri/admin/request.h>
-#include <siri/siri.h>
-#include <logger/logger.h>
-#include <pcre2.h>
-#include <lock/lock.h>
-#include <xmath/xmath.h>
-#include <unistd.h>
-#include <uuid/uuid.h>
-#include <siri/db/server.h>
-#include <siri/db/buffer.h>
-#include <siri/version.h>
-#include <siri/db/reindex.h>
-
-#define DEFAULT_TIME_PRECISION 1
-#define DEFAULT_BUFFER_SIZE 1024
-#define DEFAULT_DURATION_NUM 604800
-#define DEFAULT_DURATION_LOG 86400
-#define DB_CONF_FN "database.conf"
-#define DB_DAT_FN "database.dat"
-#define DEFAULT_CONF \
-"#\n" \
-"# Welcome to the SiriDB configuration file\n" \
-"#\n" \
-"\n" \
-"[buffer]\n" \
-"# Alternative path to save the buffer file.\n" \
-"# In case you later plan to change this location you manually need to move\n" \
-"# the buffer file to the new location.\n" \
-"# path = <buffer_path>\n" \
-"\n" \
-"# Buffer size in bytes. This size must be a multiple of 512 with a maximum\n" \
-"# of 1048576 bytes. Be careful using large values since SiriDB will require\n" \
-"# memory based on this value. A value between 1024 and 32768 is recommended.\n" \
-"# size = 1024\n"
-
-#define CHECK_DBNAME_AND_CREATE_PATH \
- pcre_exec_ret = pcre2_match( \
- siri.dbname_regex, \
- (PCRE2_SPTR8) qp_dbname.via.raw, \
- qp_dbname.len, \
- 0, \
- 0, \
- siri.dbname_match_data, \
- NULL); \
- \
- if (pcre_exec_ret < 0) \
- { \
- snprintf( \
- err_msg, \
- SIRI_MAX_SIZE_ERR_MSG, \
- "invalid database name: '%.*s'", \
- (int) qp_dbname.len, \
- qp_dbname.via.raw); \
- return CPROTO_ERR_ADMIN; \
- } \
- \
- if (llist_get( \
- siri.siridb_list, \
- (llist_cb) ADMIN_find_database, \
- &qp_dbname) != NULL) \
- { \
- snprintf( \
- err_msg, \
- SIRI_MAX_SIZE_ERR_MSG, \
- "database name already exists: '%.*s'", \
- (int) qp_dbname.len, \
- qp_dbname.via.raw); \
- return CPROTO_ERR_ADMIN; \
- } \
- \
- dbpath_len = strlen(siri.cfg->default_db_path) + qp_dbname.len + 2; \
- char dbpath[dbpath_len]; \
- sprintf(dbpath, \
- "%s%.*s/", \
- siri.cfg->default_db_path, \
- (int) qp_dbname.len, \
- qp_dbname.via.raw); \
- \
- if (stat(dbpath, &st) != -1) \
- { \
- snprintf( \
- err_msg, \
- SIRI_MAX_SIZE_ERR_MSG, \
- "database directory already exists: %s", \
- dbpath); \
- return CPROTO_ERR_ADMIN; \
- } \
- \
- if (mkdir(dbpath, 0700) == -1) \
- { \
- snprintf( \
- err_msg, \
- SIRI_MAX_SIZE_ERR_MSG, \
- "cannot create directory: %s", \
- dbpath); \
- return CPROTO_ERR_ADMIN; \
- } \
- \
- char dbfn[dbpath_len + max_filename_sz]; \
- sprintf(dbfn, "%s%s", dbpath, DB_CONF_FN); \
- \
- fp = fopen(dbfn, "w"); \
- if (fp == NULL) \
- { \
- siri_admin_request_rollback(dbpath); \
- snprintf( \
- err_msg, \
- SIRI_MAX_SIZE_ERR_MSG, \
- "cannot open file for writing: %s", \
- dbfn); \
- return CPROTO_ERR_ADMIN; \
- } \
- \
- rc = fputs(DEFAULT_CONF, fp); \
- \
- if (fclose(fp) || rc < 0) \
- { \
- siri_admin_request_rollback(dbpath); \
- snprintf( \
- err_msg, \
- SIRI_MAX_SIZE_ERR_MSG, \
- "cannot write file: %s", \
- dbfn); \
- return CPROTO_ERR_ADMIN; \
- }
-
-static cproto_server_t ADMIN_on_new_account(
- qp_unpacker_t * qp_unpacker,
- char * err_msg);
-static cproto_server_t ADMIN_on_change_password(
- qp_unpacker_t * qp_unpacker,
- char * err_msg);
-static cproto_server_t ADMIN_on_drop_account(
- qp_unpacker_t * qp_unpacker,
- qp_obj_t * qp_account,
- char * err_msg);
-static cproto_server_t ADMIN_on_new_database(
- qp_unpacker_t * qp_unpacker,
- char * err_msg);
-static cproto_server_t ADMIN_on_new_replica_or_pool(
- qp_unpacker_t * qp_unpacker,
- uint16_t pid,
- sirinet_stream_t * client,
- int req,
- char * err_msg);
-static cproto_server_t ADMIN_on_get_version(
- qp_unpacker_t * qp_unpacker,
- qp_packer_t ** packaddr,
- char * err_msg);
-static cproto_server_t ADMIN_on_get_accounts(
- qp_unpacker_t * qp_unpacker,
- qp_packer_t ** packaddr,
- char * err_msg);
-static cproto_server_t ADMIN_on_get_databases(
- qp_unpacker_t * qp_unpacker,
- qp_packer_t ** packaddr,
- char * err_msg);
-static int8_t ADMIN_time_precision(qp_obj_t * qp_time_precision);
-static int64_t ADMIN_duration(qp_obj_t * qp_duration, uint8_t time_precision);
-static int ADMIN_list_databases(siridb_t * siridb, qp_packer_t * packer);
-static int ADMIN_find_database(siridb_t * siridb, qp_obj_t * dbname);
-static int ADMIN_list_accounts(
- siri_admin_account_t * account,
- qp_packer_t * packer);
-
-static size_t max_filename_sz;
-
-/*
- * Initialize administrative requests. (called once when initializing SiriDB)
- */
-int siri_admin_request_init(void)
-{
- max_filename_sz = xmath_max_size(
- 3,
- strlen(DB_CONF_FN),
- strlen(DB_DAT_FN),
- strlen(REINDEX_FN));
-
- int pcre_error_num;
- PCRE2_SIZE pcre_error_offset;
-
- pcre2_code * regex;
- pcre2_match_data * match_data;
-
- regex = pcre2_compile(
- (PCRE2_SPTR8) "^[a-zA-Z][a-zA-Z0-9-_]{0,18}[a-zA-Z0-9]$",
- PCRE2_ZERO_TERMINATED,
- 0,
- &pcre_error_num,
- &pcre_error_offset,
- NULL);
- if (regex == NULL)
- {
- return -1;
- }
- match_data = pcre2_match_data_create_from_pattern(regex, NULL);
-
- if(match_data == NULL)
- {
- pcre2_match_data_free(match_data);
- pcre2_code_free(regex);
- return -1;
- }
-
- siri.dbname_regex = regex;
- siri.dbname_match_data = match_data;
-
- return 0;
-}
-
-/*
- * Destroy administrative requests. (only called when exiting SiriDB)
- */
-void siri_admin_request_destroy(void)
-{
- pcre2_match_data_free(siri.dbname_match_data);
- pcre2_code_free(siri.dbname_regex);
-}
-
-/*
- * Returns CPROTO_ACK_ADMIN or CPROTO_DEFERRED when successful.
- * In case of an error CPROTO_ERR_ADMIN can be returned in which case err_msg
- * is set, or CPROTO_ERR_ADMIN_INVALID_REQUEST is returned.
- */
-cproto_server_t siri_admin_request(
- int tp,
- qp_unpacker_t * qp_unpacker,
- qp_obj_t * qp_account,
- qp_packer_t ** packaddr,
- uint16_t pid,
- sirinet_stream_t * client,
- char * err_msg)
-{
- switch ((admin_request_t) tp)
- {
- case ADMIN_NEW_ACCOUNT_:
- return ADMIN_on_new_account(qp_unpacker, err_msg);
- case ADMIN_CHANGE_PASSWORD_:
- return ADMIN_on_change_password(qp_unpacker, err_msg);
- case ADMIN_DROP_ACCOUNT_:
- return ADMIN_on_drop_account(qp_unpacker, qp_account, err_msg);
- case ADMIN_NEW_DATABASE_:
- return ADMIN_on_new_database(qp_unpacker, err_msg);
- case ADMIN_NEW_POOL:
- return ADMIN_on_new_replica_or_pool(
- qp_unpacker,
- pid,
- client,
- ADMIN_NEW_POOL,
- err_msg);
- case ADMIN_NEW_REPLICA:
- return ADMIN_on_new_replica_or_pool(
- qp_unpacker,
- pid,
- client,
- ADMIN_NEW_REPLICA,
- err_msg);
- case ADMIN_GET_VERSION:
- return ADMIN_on_get_version(qp_unpacker, packaddr, err_msg);
- case ADMIN_GET_ACCOUNTS:
- return ADMIN_on_get_accounts(qp_unpacker, packaddr, err_msg);
- case ADMIN_GET_DATABASES:
- return ADMIN_on_get_databases(qp_unpacker, packaddr, err_msg);
- default:
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-}
-
-/*
- * Returns CPROTO_ACK_ADMIN when successful.
- * In case of an error CPROTO_ERR_ADMIN can be returned in which case err_msg
- * is set, or CPROTO_ERR_ADMIN_INVALID_REQUEST is returned.
- */
-static cproto_server_t ADMIN_on_new_account(
- qp_unpacker_t * qp_unpacker,
- char * err_msg)
-{
- qp_obj_t qp_key, qp_account, qp_password;
-
- qp_account.tp = QP_HOOK;
- qp_password.tp = QP_HOOK;
-
- if (!qp_is_map(qp_next(qp_unpacker, NULL)))
- {
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- while (qp_next(qp_unpacker, &qp_key) == QP_RAW)
- {
- if ( strncmp(
- (const char *) qp_key.via.raw,
- "account",
- qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_account) == QP_RAW)
- {
- continue;
- }
- if ( strncmp(
- (const char *) qp_key.via.raw,
- "password",
- qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_password) == QP_RAW)
- {
- continue;
- }
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- if (qp_account.tp == QP_HOOK || qp_password.tp == QP_HOOK)
- {
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- return (siri_admin_account_new(
- &siri,
- &qp_account,
- &qp_password,
- 0,
- err_msg) ||
- siri_admin_account_save(&siri, err_msg)) ?
- CPROTO_ERR_ADMIN : CPROTO_ACK_ADMIN;
-}
-
-/*
- * Returns CPROTO_ACK_ADMIN when successful.
- * In case of an error CPROTO_ERR_ADMIN can be returned in which case err_msg
- * is set, or CPROTO_ERR_ADMIN_INVALID_REQUEST is returned.
- */
-static cproto_server_t ADMIN_on_change_password(
- qp_unpacker_t * qp_unpacker,
- char * err_msg)
-{
- qp_obj_t qp_key, qp_account, qp_password;
-
- qp_account.tp = QP_HOOK;
- qp_password.tp = QP_HOOK;
-
- if (!qp_is_map(qp_next(qp_unpacker, NULL)))
- {
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- while (qp_next(qp_unpacker, &qp_key) == QP_RAW)
- {
- if ( strncmp(
- (const char *) qp_key.via.raw,
- "account",
- qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_account) == QP_RAW)
- {
- continue;
- }
- if ( strncmp(
- (const char *) qp_key.via.raw,
- "password",
- qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_password) == QP_RAW)
- {
- continue;
- }
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- if (qp_account.tp == QP_HOOK || qp_password.tp == QP_HOOK)
- {
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- return (siri_admin_account_change_password(
- &siri,
- &qp_account,
- &qp_password,
- err_msg) ||
- siri_admin_account_save(&siri, err_msg)) ?
- CPROTO_ERR_ADMIN : CPROTO_ACK_ADMIN;
-}
-
-/*
- * Returns CPROTO_ACK_ADMIN when successful.
- * In case of an error CPROTO_ERR_ADMIN can be returned in which case err_msg
- * is set, or CPROTO_ERR_ADMIN_INVALID_REQUEST is returned.
- */
-static cproto_server_t ADMIN_on_drop_account(
- qp_unpacker_t * qp_unpacker,
- qp_obj_t * qp_account,
- char * err_msg)
-{
- qp_obj_t qp_key, qp_target;
-
- qp_target.tp = QP_HOOK;
-
- if (!qp_is_map(qp_next(qp_unpacker, NULL)))
- {
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- while (qp_next(qp_unpacker, &qp_key) == QP_RAW)
- {
- if ( strncmp(
- (const char *) qp_key.via.raw,
- "account",
- qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_target) == QP_RAW)
- {
- continue;
- }
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- if (qp_target.tp == QP_HOOK)
- {
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- if (qp_target.len == qp_account->len &&
- strncmp(
- (const char *) qp_target.via.raw,
- (const char *) qp_account->via.raw,
- qp_target.len) == 0)
- {
- sprintf(err_msg, "cannot drop your own account");
- return CPROTO_ERR_ADMIN;
- }
-
- return (siri_admin_account_drop(
- &siri,
- &qp_target,
- err_msg) ||
- siri_admin_account_save(&siri, err_msg)) ?
- CPROTO_ERR_ADMIN : CPROTO_ACK_ADMIN;
-}
-
-/*
- * Returns CPROTO_ACK_ADMIN when successful.
- * In case of an error CPROTO_ERR_ADMIN can be returned in which case err_msg
- * is set, or CPROTO_ERR_ADMIN_INVALID_REQUEST is returned.
- */
-static cproto_server_t ADMIN_on_new_database(
- qp_unpacker_t * qp_unpacker,
- char * err_msg)
-{
- FILE * fp;
- qp_obj_t
- qp_key,
- qp_dbname,
- qp_time_precision,
- qp_buffer_size,
- qp_duration_num,
- qp_duration_log;
- size_t dbpath_len;
- int pcre_exec_ret;
- int rc;
- struct stat st;
- int8_t time_precision;
- int64_t buffer_size, duration_num, duration_log;
- siridb_t * siridb;
- uuid_t uuid;
-
- memset(&st, 0, sizeof(struct stat));
-
- if (siri.siridb_list->len == MAX_NUMBER_DB)
- {
- sprintf(err_msg,
- "maximum number of databases is reached (%zd)",
- siri.siridb_list->len);
- return CPROTO_ERR_ADMIN;
- }
-
- qp_dbname.tp = QP_HOOK;
- qp_time_precision.tp = QP_HOOK;
- qp_buffer_size.tp = QP_HOOK;
- qp_duration_num.tp = QP_HOOK;
- qp_duration_log.tp = QP_HOOK;
-
- if (!qp_is_map(qp_next(qp_unpacker, NULL)))
- {
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- while (qp_next(qp_unpacker, &qp_key) == QP_RAW)
- {
- if ( strncmp(
- (const char *) qp_key.via.raw,
- "dbname",
- qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_dbname) == QP_RAW)
- {
- continue;
- }
- if ( strncmp(
- (const char *) qp_key.via.raw,
- "time_precision",
- qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_time_precision) == QP_RAW)
- {
- continue;
- }
- if ( strncmp(
- (const char *) qp_key.via.raw,
- "buffer_size",
- qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_buffer_size) == QP_INT64)
- {
- continue;
- }
- if ( strncmp(
- (const char *) qp_key.via.raw,
- "duration_num",
- qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_duration_num) == QP_RAW)
- {
- continue;
- }
- if ( strncmp(
- (const char *) qp_key.via.raw,
- "duration_log",
- qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_duration_log) == QP_RAW)
- {
- continue;
- }
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- if (qp_dbname.tp == QP_HOOK)
- {
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- time_precision = (qp_time_precision.tp == QP_HOOK) ?
- DEFAULT_TIME_PRECISION : ADMIN_time_precision(&qp_time_precision);
- if (time_precision == -1)
- {
- snprintf(
- err_msg,
- SIRI_MAX_SIZE_ERR_MSG,
- "invalid time precision: '%.*s' (expecting s, ms, us or ns)",
- (int) qp_time_precision.len,
- qp_time_precision.via.raw);
- return CPROTO_ERR_ADMIN;
- }
-
- duration_num = (qp_duration_num.tp == QP_HOOK) ?
- DEFAULT_DURATION_NUM * xmath_ipow(1000, time_precision):
- ADMIN_duration(&qp_duration_num, time_precision);
-
- if (duration_num == -1)
- {
- snprintf(
- err_msg,
- SIRI_MAX_SIZE_ERR_MSG,
- "invalid number duration: '%.*s' "
- "(valid examples: 6h, 2d or 1w)",
- (int) qp_duration_num.len,
- qp_duration_num.via.raw);
- return CPROTO_ERR_ADMIN;
- }
-
- duration_log = (qp_duration_log.tp == QP_HOOK) ?
- DEFAULT_DURATION_LOG * xmath_ipow(1000, time_precision):
- ADMIN_duration(&qp_duration_log, time_precision);
-
- if (duration_log == -1)
- {
- snprintf(
- err_msg,
- SIRI_MAX_SIZE_ERR_MSG,
- "invalid log duration: '%.*s' "
- "(valid examples: 6h, 2d or 1w)",
- (int) qp_duration_log.len,
- qp_duration_log.via.raw);
- return CPROTO_ERR_ADMIN;
- }
-
- buffer_size = (qp_buffer_size.tp == QP_HOOK) ?
- DEFAULT_BUFFER_SIZE : qp_buffer_size.via.int64;
-
- if (!siridb_buffer_is_valid_size(buffer_size))
- {
- sprintf(err_msg,
- "invalid buffer size: %" PRId64
- " (expecting a multiple of 512 with a maximum of %" PRId64 ")",
- buffer_size,
- (int64_t) MAX_BUFFER_SZ);
- return CPROTO_ERR_ADMIN;
- }
-
- CHECK_DBNAME_AND_CREATE_PATH
-
- sprintf(dbfn, "%s%s", dbpath, DB_DAT_FN);
- fp = qp_open(dbfn, "w");
- if (fp == NULL)
- {
- siri_admin_request_rollback(dbpath);
- snprintf(
- err_msg,
- SIRI_MAX_SIZE_ERR_MSG,
- "cannot open file for writing: %s",
- dbfn);
- return CPROTO_ERR_ADMIN;
- }
- rc = 0;
- uuid_generate(uuid);
-
- if (qp_fadd_type(fp, QP_ARRAY_OPEN) ||
- qp_fadd_int8(fp, SIRIDB_SCHEMA) ||
- qp_fadd_raw(fp, (const unsigned char *) uuid, 16) ||
- qp_fadd_raw(fp, qp_dbname.via.raw, qp_dbname.len) ||
- qp_fadd_int8(fp, time_precision) ||
- qp_fadd_int64(fp, buffer_size) ||
- qp_fadd_int64(fp, duration_num) ||
- qp_fadd_int64(fp, duration_log) ||
- qp_fadd_string(fp, "NAIVE") ||
- qp_fadd_double(fp, DEF_DROP_THRESHOLD) ||
- qp_fadd_int64(fp, DEF_SELECT_POINTS_LIMIT) ||
- qp_fadd_int64(fp, DEF_LIST_LIMIT) ||
- qp_fadd_type(fp, QP_ARRAY_CLOSE))
- {
- rc = -1;
- }
-
- if (qp_close(fp) || rc == -1)
- {
- siri_admin_request_rollback(dbpath);
- snprintf(
- err_msg,
- SIRI_MAX_SIZE_ERR_MSG,
- "cannot write file: %s",
- dbfn);
- return CPROTO_ERR_ADMIN;
- }
-
- siridb = siridb_new(dbpath, LOCK_QUIT_IF_EXIST);
- if (siridb == NULL)
- {
- siri_admin_request_rollback(dbpath);
- sprintf(err_msg, "error loading database");
- return CPROTO_ERR_ADMIN;
- }
-
- siridb->server->flags |= SERVER_FLAG_RUNNING;
-
- /* Force one heart-beat */
- siri_heartbeat_force();
-
- return CPROTO_ACK_ADMIN;
-}
-
-/*
- * Returns CPROTO_DEFERRED when successful.
- * In case of an error CPROTO_ERR_ADMIN can be returned in which case err_msg
- * is set, or CPROTO_ERR_ADMIN_INVALID_REQUEST is returned.
- */
-static cproto_server_t ADMIN_on_new_replica_or_pool(
- qp_unpacker_t * qp_unpacker,
- uint16_t pid,
- sirinet_stream_t * client,
- int req,
- char * err_msg)
-{
- FILE * fp;
- qp_obj_t
- qp_key,
- qp_dbname,
- qp_pool,
- qp_host,
- qp_port,
- qp_username,
- qp_password;
- size_t dbpath_len;
- int pcre_exec_ret;
- int rc;
- struct stat st;
- uint16_t port;
- uuid_t uuid;
-
- memset(&st, 0, sizeof(struct stat));
-
- if (siri.siridb_list->len == MAX_NUMBER_DB)
- {
- sprintf(err_msg,
- "maximum number of databases is reached (%zd)",
- siri.siridb_list->len);
- return CPROTO_ERR_ADMIN;
- }
-
- qp_dbname.tp = QP_HOOK;
- qp_pool.tp = QP_HOOK;
- qp_host.tp = QP_HOOK;
- qp_port.tp = QP_HOOK;
- qp_username.tp = QP_HOOK;
- qp_password.tp = QP_HOOK;
-
- if (!qp_is_map(qp_next(qp_unpacker, NULL)))
- {
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- while (qp_next(qp_unpacker, &qp_key) == QP_RAW)
- {
- if ( strncmp(
- (const char *) qp_key.via.raw,
- "dbname",
- qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_dbname) == QP_RAW)
- {
- continue;
- }
- if ( strncmp(
- (const char *) qp_key.via.raw, "pool", qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_pool) == QP_INT64)
- {
- continue;
- }
- if ( strncmp(
- (const char *) qp_key.via.raw, "host", qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_host) == QP_RAW)
- {
- continue;
- }
- if ( strncmp(
- (const char *) qp_key.via.raw, "port", qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_port) == QP_INT64)
- {
- continue;
- }
- if ( strncmp(
- (const char *) qp_key.via.raw,
- "username",
- qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_username) == QP_RAW)
- {
- continue;
- }
- if ( strncmp(
- (const char *) qp_key.via.raw,
- "password",
- qp_key.len) == 0 &&
- qp_next(qp_unpacker, &qp_password) == QP_RAW)
- {
- continue;
- }
-
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- if (qp_dbname.tp == QP_HOOK ||
- (
- (req == ADMIN_NEW_POOL && qp_pool.tp != QP_HOOK) ||
- (req == ADMIN_NEW_REPLICA && qp_pool.tp == QP_HOOK)
- ) ||
- qp_host.tp == QP_HOOK ||
- qp_port.tp == QP_HOOK ||
- qp_username.tp == QP_HOOK ||
- qp_password.tp == QP_HOOK)
- {
- return CPROTO_ERR_ADMIN_INVALID_REQUEST;
- }
-
- if (qp_port.via.int64 < 1 || qp_port.via.int64 > 65535)
- {
- sprintf(err_msg,
- "invalid port number: %" PRId64
- " (expecting a value between 0 and 65536)",
- qp_port.via.int64);
- return CPROTO_ERR_ADMIN;
- }
-
- port = (uint16_t) qp_port.via.int64;
- uuid_generate(uuid);
-
- CHECK_DBNAME_AND_CREATE_PATH
-
- if (req == ADMIN_NEW_POOL)
- {
- sprintf(dbfn, "%s%s", dbpath, REINDEX_FN);
- fp = fopen(dbfn, "w");
- if (fp == NULL || fclose(fp))
- {
- siri_admin_request_rollback(dbpath);
- snprintf(
- err_msg,
- SIRI_MAX_SIZE_ERR_MSG,
- "cannot open file for writing: %s",
- dbfn);
- return CPROTO_ERR_ADMIN;
- }
- }
-
- if (siri_admin_client_request(
- pid,
- port,
- /* -1 = new pool */
- (req == ADMIN_NEW_POOL) ? -1 : qp_pool.via.int64,
- &uuid,
- &qp_host,
- &qp_username,
- &qp_password,
- &qp_dbname,
- dbpath,
- client,
- err_msg))
- {
- siri_admin_request_rollback(dbpath);
- return CPROTO_ERR_ADMIN;
- }
- return CPROTO_DEFERRED;
-}
-
-/*
- * Returns CPROTO_ACK_ADMIN_DATA when successful.
- * In case of an error CPROTO_ERR_ADMIN will be returned and err_msg is set
- */
-static cproto_server_t ADMIN_on_get_version(
- qp_unpacker_t * qp_unpacker __attribute__((unused)),
- qp_packer_t ** packaddr,
- char * err_msg)
-{
- qp_packer_t * packer = sirinet_packer_new(128);
- if (packer != NULL)
- {
- if (!qp_add_type(packer, QP_ARRAY_OPEN) &&
- !qp_add_string(packer, SIRIDB_VERSION))
- {
- *packaddr = packer;
- return CPROTO_ACK_ADMIN_DATA;
- }
-
- /* error, free packer */
- qp_packer_free(packer);
- }
- sprintf(err_msg, "memory allocation error");
- return CPROTO_ERR_ADMIN;
-}
-
-static cproto_server_t ADMIN_on_get_accounts(
- qp_unpacker_t * qp_unpacker __attribute__((unused)),
- qp_packer_t ** packaddr,
- char * err_msg)
-{
- qp_packer_t * packer = sirinet_packer_new(128);
-
- if (packer != NULL)
- {
- qp_add_type(packer, QP_ARRAY_OPEN);
-
- if (!llist_walk(
- siri.accounts,
- (llist_cb) ADMIN_list_accounts,
- packer))
- {
- *packaddr = packer;
- return CPROTO_ACK_ADMIN_DATA;
- }
-
- /* error, free packer */
- qp_packer_free(packer);
- }
- sprintf(err_msg, "memory allocation error");
- return CPROTO_ERR_ADMIN;
-}
-
-static cproto_server_t ADMIN_on_get_databases(
- qp_unpacker_t * qp_unpacker __attribute__((unused)),
- qp_packer_t ** packaddr,
- char * err_msg)
-{
- qp_packer_t * packer = sirinet_packer_new(128);
-
- if (packer != NULL)
- {
- qp_add_type(packer, QP_ARRAY_OPEN);
-
- if (!llist_walk(
- siri.siridb_list,
- (llist_cb) ADMIN_list_databases,
- packer))
- {
- *packaddr = packer;
- return CPROTO_ACK_ADMIN_DATA;
- }
-
- /* error, free packer */
- qp_packer_free(packer);
- }
- sprintf(err_msg, "memory allocation error");
- return CPROTO_ERR_ADMIN;
-}
-
-void siri_admin_request_rollback(const char * dbpath)
-{
- size_t dbpath_len = strlen(dbpath);
- char dbfn[dbpath_len + max_filename_sz];
-
- sprintf(dbfn, "%s%s", dbpath, DB_CONF_FN);
- unlink(dbfn);
- sprintf(dbfn, "%s%s", dbpath, DB_DAT_FN);
- unlink(dbfn);
- sprintf(dbfn, "%s%s", dbpath, REINDEX_FN);
- unlink(dbfn);
- if (rmdir(dbpath))
- {
- log_error("Roll-back creating new database has failed.");
- }
-}
-
-static int8_t ADMIN_time_precision(qp_obj_t * qp_time_precision)
-{
- if (qp_time_precision->tp != QP_RAW)
- {
- return -1;
- }
- if (qp_time_precision->len == 1 && qp_time_precision->via.raw[0] == 's')
- {
- return 0;
- }
- else if (qp_time_precision->len == 2 && qp_time_precision->via.raw[1] == 's')
- {
- switch (qp_time_precision->via.raw[0])
- {
- case 'm': return 1;
- case 'u': return 2;
- case 'n': return 3;
- }
- }
- return -1;
-}
-
-static int64_t ADMIN_duration(qp_obj_t * qp_duration, uint8_t time_precision)
-{
- char * endptr;
- long int val;
-
- if (qp_duration->tp != QP_RAW || qp_duration->len < 2)
- {
- return -1;
- }
-
- val = strtol((const char *) qp_duration->via.raw, &endptr, 10);
-
- if (val < 1 || val > 99 || endptr == (const char *) qp_duration->via.raw)
- {
- return -1;
- }
-
- if (endptr != (const char *) qp_duration->via.raw + (qp_duration->len - 1))
- {
- return -1;
- }
-
- switch (*endptr)
- {
- case 'h': return xmath_ipow(1000, time_precision) * val * 3600;
- case 'd': return xmath_ipow(1000, time_precision) * val * 86400;
- case 'w': return xmath_ipow(1000, time_precision) * val * 604800;
- }
-
- return -1;
-}
-
-static int ADMIN_list_databases(siridb_t * siridb, qp_packer_t * packer)
-{
- return qp_add_string(packer, siridb->dbname);
-}
-
-static int ADMIN_find_database(siridb_t * siridb, qp_obj_t * dbname)
-{
- return (
- strlen(siridb->dbname) == dbname->len &&
- strncmp(
- siridb->dbname,
- (const char *) dbname->via.raw,
- dbname->len) == 0);
-}
-
-static int ADMIN_list_accounts(
- siri_admin_account_t * account,
- qp_packer_t * packer)
-{
- return qp_add_string(packer, account->account);
-}
+/*
+ * args.c - Parse SiriDB command line arguments.
+ */
#include <siri/args/args.h>
#include <argparse/argparse.h>
#include <siri/version.h>
/*
- * async.c - SiriDB async wrapper
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- *
- * changes
- * - initial version, 21-07-2016
- *
+ * async.c - SiriDB async wrapper.
*/
#include <logger/logger.h>
#include <siri/async.h>
/*
* backup.c - Set SiriDB in backup mode.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 27-09-2016
- *
*/
#include <assert.h>
#include <logger/logger.h>
* A lock is not needed since the optimize thread is paused and this
* is running from the main thread.
*/
- slist_t * shard_list = imap_2slist(siridb->shards);
+ vec_t * shard_list = imap_2vec(siridb->shards);
if (shard_list == NULL)
{
}
}
- slist_free(shard_list);
+ vec_free(shard_list);
}
}
/*
* buffersync.c - Buffer sync.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2018, Transceptor Technology
- *
*/
#include <logger/logger.h>
#include <siri/db/server.h>
+/*
+ * cfg.h - Read the global SiriDB configuration file. (usually siridb.conf)
+ */
#include <cfgparser/cfgparser.h>
#include <inttypes.h>
#include <limits.h>
#include <siri/cfg/cfg.h>
#include <stdio.h>
#include <stdlib.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
#include <string.h>
#include <unistd.h>
#include <sys/resource.h>
if ( !strlen(address) ||
strlen(address) >= SIRI_CFG_MAX_LEN_ADDRESS ||
- !strx_is_int(port) ||
+ !xstr_is_int(port) ||
strcpy(address_pt, address) == NULL ||
- strx_replace_str(
+ xstr_replace_str(
address_pt,
"%HOSTNAME",
hostname,
/*
* access.c - Access constants and functions.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 13-03-2016
- *
*/
#include <siri/db/access.h>
#include <stdio.h>
/*
* aggregate.c - SiriDB aggregation methods.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 15-04-2016
- *
*/
#include <assert.h>
#include <limits.h>
#include <siri/db/variance.h>
#include <siri/grammar/grammar.h>
#include <siri/db/re.h>
-#include <slist/slist.h>
+#include <vec/vec.h>
#include <stddef.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
#include <math.h>
#define AGGR_NEW \
if ((aggr = AGGREGATE_new(gid)) == NULL) \
{ \
sprintf(err_msg, "Memory allocation error."); \
- siridb_aggregate_list_free(slist); \
+ siridb_aggregate_list_free(vec); \
return NULL; \
}
-#define SLIST_APPEND \
-if (slist_append_safe(&slist, aggr)) \
+#define VEC_APPEND \
+if (vec_append_safe(&vec, aggr)) \
{ \
sprintf(err_msg, "Memory allocation error."); \
AGGREGATE_free(aggr); \
- siridb_aggregate_list_free(slist); \
+ siridb_aggregate_list_free(vec); \
return NULL; \
}
/*
* Returns NULL in case an error has occurred and the err_msg will be set.
*/
-slist_t * siridb_aggregate_list(cleri_children_t * children, char * err_msg)
+vec_t * siridb_aggregate_list(cleri_children_t * children, char * err_msg)
{
uint32_t gid;
siridb_aggr_t * aggr;
- slist_t * slist = slist_new(SLIST_DEFAULT_SIZE);
- if (slist == NULL)
+ vec_t * vec = vec_new(VEC_DEFAULT_SIZE);
+ if (vec == NULL)
{
sprintf(err_msg, "Memory allocation error.");
return NULL;
"Limit must be an integer value "
"larger than zero.");
AGGREGATE_free(aggr);
- siridb_aggregate_list_free(slist);
+ siridb_aggregate_list_free(vec);
return NULL;
}
}
}
- SLIST_APPEND
+ VEC_APPEND
break;
if (AGGREGATE_init_filter(aggr, onode, err_msg))
{
AGGREGATE_free(aggr);
- siridb_aggregate_list_free(slist);
+ siridb_aggregate_list_free(vec);
return NULL; /* err_msg is set */
}
}
- SLIST_APPEND
+ VEC_APPEND
break;
"Time-span must be an integer value "
"larger than zero.");
AGGREGATE_free(aggr);
- siridb_aggregate_list_free(slist);
+ siridb_aggregate_list_free(vec);
return NULL;
}
"Group by time must be an integer "
"value larger than zero.");
AGGREGATE_free(aggr);
- siridb_aggregate_list_free(slist);
+ siridb_aggregate_list_free(vec);
return NULL;
}
}
}
- SLIST_APPEND
+ VEC_APPEND
break;
"Group by time must be an integer value "
"larger than zero.");
AGGREGATE_free(aggr);
- siridb_aggregate_list_free(slist);
+ siridb_aggregate_list_free(vec);
return NULL;
}
}
- SLIST_APPEND
+ VEC_APPEND
break;
children = children->next->next;
}
- return slist;
+ return vec;
}
/*
* Destroy aggregates list. (parsing NULL is not allowed)
*/
-void siridb_aggregate_list_free(slist_t * alist)
+void siridb_aggregate_list_free(vec_t * alist)
{
size_t i;
for (i = 0; i < alist->len; i++)
case CLERI_GID_R_FLOAT:
aggr->filter_tp = TP_DOUBLE;
- aggr->filter_via.real = strx_to_double(node->str, node->len);
+ aggr->filter_via.real = xstr_to_double(node->str, node->len);
break;
case CLERI_GID_STRING:
sprintf(err_msg, "Memory allocation error.");
return -1;
}
- strx_extract_string(
+ xstr_extract_string(
(char *) aggr->filter_via.raw, node->str, node->len);
return 0;
/*
* auth.c - Handle SiriDB authentication.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-03-2016
- *
*/
#include <assert.h>
#include <logger/logger.h>
/*
- * buffer.c - Buffer for integer and double series.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 01-04-2016
- *
+ * buffer.c - Buffer for integer and double values.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
{
return NULL;
}
- buffer->empty = slist_new(SLIST_DEFAULT_SIZE);
+ buffer->empty = vec_new(VEC_DEFAULT_SIZE);
if (buffer->empty == NULL)
{
free(buffer);
}
free(buffer->template);
free(buffer->path);
- slist_free(buffer->empty);
+ vec_free(buffer->empty);
free(buffer);
}
siridb_buffer_t * buffer,
siridb_series_t * series)
{
- series->bf_offset = (long int) slist_pop(buffer->empty);
+ series->bf_offset = (long int) vec_pop(buffer->empty);
if (siridb_buffer_write_empty(buffer, series))
{
while ((buffer_pos -= buffer->size) > series->bf_offset)
{
- slist_append_safe(&buffer->empty, (void *) buffer_pos);
+ vec_append_safe(&buffer->empty, (void *) buffer_pos);
}
return 0;
/*
- * db.c - contains functions and constants for a SiriDB database.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-03-2016
- *
+ * db.c - SiriDB database.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#include <string.h>
#include <uuid/uuid.h>
#include <xpath/xpath.h>
-#include <slist/slist.h>
+#include <vec/vec.h>
#include <timeit/timeit.h>
/*
log_info("Updating series properties");
/* create a copy since 'siridb_series_update_props' might drop a series */
- slist_t * slist = imap_2slist(siridb->series_map);
+ vec_t * vec = imap_2vec(siridb->series_map);
- if (slist == NULL)
+ if (vec == NULL)
{
log_error("Could update series properties for database '%s'",
siridb->dbname);
return NULL;
}
- for (i = 0; i < slist->len; i++)
+ for (i = 0; i < vec->len; i++)
{
- siridb_series_update_props(siridb, (siridb_series_t * )slist->data[i]);
+ siridb_series_update_props(siridb, (siridb_series_t * )vec->data[i]);
}
- slist_free(slist);
+ vec_free(vec);
/* generate pools, this can raise a signal */
log_info("Initialize pools");
/*
* ffile.c - FIFO file.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 30-06-2016
- *
- *
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
/*
* fifo.c - First in, first out file buffer .
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 30-06-2016
- *
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
/*
- * forward.c - Handle forwarding series while re-indexing
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 31-07-2016
- *
+ * forward.c - Handle forwarding series while re-indexing.
*/
#include <qpack/qpack.h>
#include <siri/async.h>
#include <siri/net/protocol.h>
#include <stddef.h>
-static void FORWARD_on_response(slist_t * promises, uv_async_t * handle);
+static void FORWARD_on_response(vec_t * promises, uv_async_t * handle);
static void FORWARD_free(uv_handle_t * handle);
/*
*
* This function can raise a SIGNAL.
*/
-static void FORWARD_on_response(slist_t * promises, uv_async_t * handle)
+static void FORWARD_on_response(vec_t * promises, uv_async_t * handle)
{
if (promises != NULL)
{
/*
* group.c - Group (saved regular expressions).
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 16-08-2016
- *
*/
#include <assert.h>
#include <siri/db/db.h>
#include <siri/db/series.h>
#include <siri/err.h>
#include <siri/grammar/grammar.h>
-#include <slist/slist.h>
+#include <vec/vec.h>
#include <stdlib.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
#define SIRIDB_MIN_GROUP_LEN 1
#define SIRIDB_MAX_GROUP_LEN 255
group->flags = GROUP_FLAG_INIT;
group->name = NULL;
group->source = strndup(source, source_len);
- group->series = slist_new(SLIST_DEFAULT_SIZE);
+ group->series = vec_new(VEC_DEFAULT_SIZE);
group->regex = NULL;
group->match_data = NULL;
group->series->len -= dropped;
- slist_compact(&group->series);
+ vec_compact(&group->series);
}
/*
if (rc >= 0)
{
- if (slist_append_safe(&group->series, series))
+ if (vec_append_safe(&group->series, series))
{
log_critical(
"Cannot append series '%s' to group '%s'",
group->series->len = 0;
- slist_compact(&group->series);
+ vec_compact(&group->series);
if (~group->flags & GROUP_FLAG_INIT)
{
group->flags |= GROUP_FLAG_INIT;
- if (slist_append_safe(&groups->ngroups, group))
+ if (vec_append_safe(&groups->ngroups, group))
{
/* we log critical since allocation errors are critical, this does
* however not influence the running SiriDB in is not critical in that
series = (siridb_series_t *) group->series->data[i];
siridb_series_decref(series);
}
- slist_free(group->series);
+ vec_free(group->series);
}
pcre2_code_free(group->regex);
/*
* groups.c - Groups (saved regular expressions).
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 16-08-2016
- *
* Info groups->mutex:
*
* Main thread:
#include <siri/err.h>
#include <siri/net/protocol.h>
#include <siri/siri.h>
-#include <slist/slist.h>
+#include <vec/vec.h>
#include <stdlib.h>
#include <unistd.h>
#include <xpath/xpath.h>
static int GROUPS_write(siridb_group_t * group, qp_fpacker_t * fpacker);
static void GROUPS_init_groups(siridb_t * siridb);
static void GROUPS_init_series(siridb_t * siridb);
-static int GROUPS_2slist(siridb_group_t * group, slist_t * groups_list);
+static int GROUPS_2vec(siridb_group_t * group, vec_t * groups_list);
static void GROUPS_cleanup(siridb_groups_t * groups);
/*
* In case of an error the return value is NULL and a SIGNAL is raised.
groups->ref = 2; /* for the main thread and for the groups thread */
groups->fn = NULL;
groups->groups = ct_new();
- groups->nseries = slist_new(SLIST_DEFAULT_SIZE);
- groups->ngroups = slist_new(SLIST_DEFAULT_SIZE);
+ groups->nseries = vec_new(VEC_DEFAULT_SIZE);
+ groups->ngroups = vec_new(VEC_DEFAULT_SIZE);
uv_mutex_init(&groups->mutex);
groups->work.data = (siridb_t *) siridb;
uv_mutex_lock(&groups->mutex);
- if (slist_append_safe(&groups->nseries, series) == 0)
+ if (vec_append_safe(&groups->nseries, series) == 0)
{
siridb_series_incref(series);
}
break;
case CT_OK:
- if (slist_append_safe(&groups->ngroups, group))
+ if (vec_append_safe(&groups->ngroups, group))
{
siridb_group_decref(group);
sprintf(err_msg, "Memory allocation error.");
series = (siridb_series_t *) groups->nseries->data[i];
siridb_series_decref(series);
}
- slist_free(groups->nseries);
+ vec_free(groups->nseries);
}
if (groups->groups != NULL)
group = (siridb_group_t *) groups->ngroups->data[i];
siridb_group_decref(group);
}
- slist_free(groups->ngroups);
+ vec_free(groups->ngroups);
}
uv_mutex_destroy(&groups->mutex);
/*
* Group thread.
*/
-static int GROUPS_2slist(siridb_group_t * group, slist_t * groups_list)
+static int GROUPS_2vec(siridb_group_t * group, vec_t * groups_list)
{
siridb_group_incref(group);
- slist_append(groups_list, group);
+ vec_append(groups_list, group);
return 0;
}
while (groups->nseries->len)
{
- series = (siridb_series_t *) slist_pop(groups->nseries);
+ series = (siridb_series_t *) vec_pop(groups->nseries);
if (~series->flags & SIRIDB_SERIES_IS_DROPPED)
{
{
siridb_groups_t * groups = siridb->groups;
siridb_group_t * group;
- slist_t * series_list;
+ vec_t * series_list;
siridb_series_t * series;
size_t i;
uv_mutex_lock(&siridb->series_mutex);
series_list = (groups->nseries->len) ?
- NULL : imap_2slist_ref(siridb->series_map);
+ NULL : imap_2vec_ref(siridb->series_map);
uv_mutex_unlock(&siridb->series_mutex);
while (groups->ngroups->len)
{
- group = (siridb_group_t *) slist_pop(groups->ngroups);
+ group = (siridb_group_t *) vec_pop(groups->ngroups);
/* we must be sure this group is empty */
assert (group->series->len == 0);
siridb_series_decref(series);
}
- slist_free(series_list);
+ vec_free(series_list);
}
/*
groups->flags &= ~GROUPS_FLAG_DROPPED_SERIES;
- slist_t * groups_list = slist_new(groups->groups->len);
+ vec_t * groups_list = vec_new(groups->groups->len);
if (groups_list != NULL)
{
- ct_values(groups->groups, (ct_val_cb) GROUPS_2slist, groups_list);
+ ct_values(groups->groups, (ct_val_cb) GROUPS_2vec, groups_list);
}
uv_mutex_unlock(&groups->mutex);
while (groups_list->len)
{
- group = (siridb_group_t *) slist_pop(groups_list);
+ group = (siridb_group_t *) vec_pop(groups_list);
if (!group->flags)
{
usleep(10000); /* 10ms */
}
- slist_free(groups_list);
+ vec_free(groups_list);
}
/*
- * initsync.c - Initial replica synchronization
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 22-07-2016
- *
+ * initsync.c - Initial replica synchronization.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
/*
* insert.c - Handler database inserts.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 24-03-2016
- *
*/
#include <assert.h>
#include <logger/logger.h>
static void INSERT_free(uv_handle_t * handle);
static void INSERT_points_to_pools(uv_async_t * handle);
-static void INSERT_on_response(slist_t * promises, uv_async_t * handle);
+static void INSERT_on_response(vec_t * promises, uv_async_t * handle);
static uint16_t INSERT_get_pool(siridb_t * siridb, qp_obj_t * qp_series_name);
static void INSERT_local_free_cb(uv_async_t * handle);
*
* This function can raise a SIGNAL.
*/
-static void INSERT_on_response(slist_t * promises, uv_async_t * handle)
+static void INSERT_on_response(vec_t * promises, uv_async_t * handle)
{
if (promises != NULL)
{
NULL);
sirinet_promises_t * promises = (sirinet_promises_t *) promise->data;
promise->data = pkg;
- slist_append(promises->promises, (void *) promise);
+ vec_append(promises->promises, (void *) promise);
SIRINET_PROMISES_CHECK(promises)
}
/*
- * listener.c - contains functions for processing queries.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-03-2016
- *
+ * listener.c - Contains functions for processing queries.
*/
#include <assert.h>
#include <cexpr/cexpr.h>
#include <siri/net/protocol.h>
#include <siri/net/clserver.h>
#include <siri/siri.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
#include <sys/time.h>
sirinet_promise_t * promise,
sirinet_pkg_t * pkg,
int status);
-static void on_alter_xxx_response(slist_t * promises, uv_async_t * handle);
-static void on_count_xxx_response(slist_t * promises, uv_async_t * handle);
-static void on_drop_series_response(slist_t * promises, uv_async_t * handle);
-static void on_drop_shards_response(slist_t * promises, uv_async_t * handle);
-static void on_groups_response(slist_t * promises, uv_async_t * handle);
-static void on_list_xxx_response(slist_t * promises, uv_async_t * handle);
-static void on_select_response(slist_t * promises, uv_async_t * handle);
-static void on_update_xxx_response(slist_t * promises, uv_async_t * handle);
+static void on_alter_xxx_response(vec_t * promises, uv_async_t * handle);
+static void on_count_xxx_response(vec_t * promises, uv_async_t * handle);
+static void on_drop_series_response(vec_t * promises, uv_async_t * handle);
+static void on_drop_shards_response(vec_t * promises, uv_async_t * handle);
+static void on_groups_response(vec_t * promises, uv_async_t * handle);
+static void on_list_xxx_response(vec_t * promises, uv_async_t * handle);
+static void on_select_response(vec_t * promises, uv_async_t * handle);
+static void on_update_xxx_response(vec_t * promises, uv_async_t * handle);
/* helper functions */
static void master_select_work(uv_work_t * handle);
static int items_select_master_merge(
const char * name,
size_t len,
- slist_t * plist,
+ vec_t * plist,
uv_async_t * handle);
static int items_select_other(
const char * name,
static int items_select_other_merge(
const char * name,
size_t len,
- slist_t * plist,
+ vec_t * plist,
uv_async_t * handle);
static void on_select_unpack_points(
qp_unpacker_t * unpacker,
siridb_group_t * group;
char name[group_node->len - 1];
- strx_extract_string(name, group_node->str, group_node->len);
+ xstr_extract_string(name, group_node->str, group_node->len);
if ((group = ct_get(siridb->groups->groups, name)) == NULL)
{
siridb_user_t * user;
char name[user_node->len - 1];
- strx_extract_string(name, user_node->str, user_node->len);
+ xstr_extract_string(name, user_node->str, user_node->len);
if ((user = siridb_users_get_user(siridb, name, NULL)) == NULL)
{
query->nodes->node->children->next->node;
siridb_user_t * user;
char username[user_node->len - 1];
- strx_extract_string(username, user_node->str, user_node->len);
+ xstr_extract_string(username, user_node->str, user_node->len);
if ((user = siridb_users_get_user(siridb, username, NULL)) == NULL)
{
char group_name[node->len - 1];
/* extract series name */
- strx_extract_string(group_name, node->str, node->len);
+ xstr_extract_string(group_name, node->str, node->len);
siridb_group_t * group =
(siridb_group_t *) ct_get(siridb->groups->groups, group_name);
query->free_cb = (uv_close_cb) query_help_free;
- strx_split_join(query->data, ' ', '_');
+ xstr_split_join(query->data, ' ', '_');
SIRIPARSER_ASYNC_NEXT_NODE
}
MEM_ERR_RET
}
- strx_extract_string(q_select->merge_as, node->str, node->len);
+ xstr_extract_string(q_select->merge_as, node->str, node->len);
if (IS_MASTER && query->nodes->node->children->next->next->next != NULL)
{
query->nodes->node->children->next->node;
siridb_user_t * user;
char username[user_node->len - 1];
- strx_extract_string(username, user_node->str, user_node->len);
+ xstr_extract_string(username, user_node->str, user_node->len);
if ((user = siridb_users_get_user(siridb, username, NULL)) == NULL)
{
query->nodes->node->children->next->next->node;
char name[name_node->len - 1];
- strx_extract_string(name, name_node->str, name_node->len);
+ xstr_extract_string(name, name_node->str, name_node->len);
query_alter_t * q_alter = (query_alter_t *) query->data;
switch (q_alter->alter_tp)
query->nodes->node->children->next->next->node;
char password[pw_node->len - 1];
- strx_extract_string(password, pw_node->str, pw_node->len);
+ xstr_extract_string(password, pw_node->str, pw_node->len);
if (siridb_user_set_password(user, password, query->err_msg))
{
char series_name[node->len - 1];
/* extract series name */
- strx_extract_string(series_name, node->str, node->len);
+ xstr_extract_string(series_name, node->str, node->len);
if (siridb_is_reindexing(siridb))
{
uv_mutex_lock(&siridb->series_mutex);
- q_wrapper->slist = imap_2slist_ref(
+ q_wrapper->vec = imap_2vec_ref(
( q_wrapper->update_cb == NULL ||
q_wrapper->update_cb == &imap_union_ref ||
q_wrapper->update_cb == &imap_symmetric_difference_ref) ?
q_wrapper->series_tmp = (q_wrapper->update_cb == NULL) ?
q_wrapper->series_map : imap_new();
- if (q_wrapper->slist == NULL || q_wrapper->series_tmp == NULL)
+ if (q_wrapper->vec == NULL || q_wrapper->series_tmp == NULL)
{
MEM_ERR_RET
}
- for (q_wrapper->slist_index = 0;
- q_wrapper->slist_index < q_wrapper->slist->len;
- ++q_wrapper->slist_index)
+ for (q_wrapper->vec_index = 0;
+ q_wrapper->vec_index < q_wrapper->vec->len;
+ ++q_wrapper->vec_index)
{
- series = q_wrapper->slist->data[q_wrapper->slist_index];
+ series = q_wrapper->vec->data[q_wrapper->vec_index];
if (imap_add(q_wrapper->series_tmp, series->id, series))
{
MEM_ERR_RET
}
}
- slist_free(q_wrapper->slist);
- q_wrapper->slist = NULL;
- q_wrapper->slist_index = 0;
+ vec_free(q_wrapper->vec);
+ q_wrapper->vec = NULL;
+ q_wrapper->vec_index = 0;
if (q_wrapper->update_cb != NULL)
{
{
uv_mutex_lock(&siridb->series_mutex);
- q_wrapper->slist = imap_2slist_ref(
+ q_wrapper->vec = imap_2vec_ref(
( q_wrapper->update_cb == NULL ||
q_wrapper->update_cb == &imap_union_ref ||
q_wrapper->update_cb == &imap_symmetric_difference_ref) ?
q_wrapper->series_tmp = (q_wrapper->update_cb == NULL) ?
q_wrapper->series_map : imap_new();
- if (q_wrapper->slist == NULL || q_wrapper->series_tmp == NULL)
+ if (q_wrapper->vec == NULL || q_wrapper->series_tmp == NULL)
{
MEM_ERR_RET
}
cleri_children_t * columns = query->nodes->node->children;
query_list_t * qlist = (query_list_t *) query->data;
- qlist->props = slist_new(DEFAULT_ALLOC_COLUMNS);
+ qlist->props = vec_new(DEFAULT_ALLOC_COLUMNS);
if (qlist->props == NULL)
{
(const unsigned char *) columns->node->str,
columns->node->len);
- if (slist_append_safe(
+ if (vec_append_safe(
&qlist->props,
&columns->node->children->node->cl_obj->gid))
{
{
uv_mutex_lock(&siridb->series_mutex);
- q_count->slist = imap_2slist_ref(
+ q_count->vec = imap_2vec_ref(
(q_count->series_map == NULL) ?
siridb->series_map : q_count->series_map);
uv_mutex_unlock(&siridb->series_mutex);
- if (q_count->slist == NULL)
+ if (q_count->vec == NULL)
{
MEM_ERR_RET
}
if (q_count->where_expr == NULL)
{
size_t i;
- slist_t * slist;
+ vec_t * vec;
siridb_series_t * series;
uv_mutex_lock(&siridb->series_mutex);
- slist = imap_2slist((q_count->series_map == NULL) ?
+ vec = imap_2vec((q_count->series_map == NULL) ?
siridb->series_map : q_count->series_map);
uv_mutex_unlock(&siridb->series_mutex);
- if (slist == NULL)
+ if (vec == NULL)
{
MEM_ERR_RET
}
- for (i = 0; i < slist->len; i++)
+ for (i = 0; i < vec->len; i++)
{
- series = (siridb_series_t *) slist->data[i];
+ series = (siridb_series_t *) vec->data[i];
q_count->n += series->length;
}
- slist_free(slist);
+ vec_free(vec);
if (IS_MASTER)
{
uv_mutex_lock(&siridb->series_mutex);
- q_count->slist = imap_2slist_ref(
+ q_count->vec = imap_2vec_ref(
(q_count->series_map == NULL) ?
siridb->series_map : q_count->series_map);
uv_mutex_unlock(&siridb->series_mutex);
- if (q_count->slist == NULL)
+ if (q_count->vec == NULL)
{
MEM_ERR_RET
}
.server=siridb->server
};
size_t i;
- slist_t * shards_list;
+ vec_t * shards_list;
uv_mutex_lock(&siridb->shards_mutex);
- shards_list = imap_2slist_ref(siridb->shards);
+ shards_list = imap_2vec_ref(siridb->shards);
uv_mutex_unlock(&siridb->shards_mutex);
siridb_shard_decref(vshard.shard);
}
- slist_free(shards_list);
+ vec_free(shards_list);
}
if (IS_MASTER)
query_count_t * q_count = (query_count_t *) query->data;
uint64_t duration;
size_t i;
- slist_t * shards_list;
+ vec_t * shards_list;
siridb_shard_view_t vshard = {
.server=siridb->server
};
uv_mutex_lock(&siridb->shards_mutex);
- shards_list = imap_2slist_ref(siridb->shards);
+ shards_list = imap_2vec_ref(siridb->shards);
uv_mutex_unlock(&siridb->shards_mutex);
siridb_shard_decref(vshard.shard);
}
- slist_free(shards_list);
+ vec_free(shards_list);
if (IS_MASTER)
{
MASTER_CHECK_ACCESSIBLE(siridb)
char group_name[name_nd->len - 1];
- strx_extract_string(group_name, name_nd->str, name_nd->len);
+ xstr_extract_string(group_name, name_nd->str, name_nd->len);
if (siridb_groups_add_group(
siridb->groups,
MASTER_CHECK_ACCESSIBLE(siridb)
char name[user_node->len - 1];
- strx_extract_string(name, user_node->str, user_node->len);
+ xstr_extract_string(name, user_node->str, user_node->len);
if (siridb_user_set_name(
siridb,
char name[group_node->len - 1];
- strx_extract_string(name, group_node->str, group_node->len);
+ xstr_extract_string(name, group_node->str, group_node->len);
if (siridb_groups_drop_group(siridb->groups, name, query->err_msg))
{
MASTER_CHECK_ACCESSIBLE(siridb)
/*
- * We transform or copy the references from imap to slist because we need
+ * We transform or copy the references from imap to vec because we need
* this list for both filtering or performing the actual drop.
*/
uv_mutex_lock(&siridb->series_mutex);
- q_drop->slist = (q_drop->series_map == NULL) ?
- imap_2slist_ref(siridb->series_map) :
- imap_slist_pop(q_drop->series_map);
+ q_drop->vec = (q_drop->series_map == NULL) ?
+ imap_2vec_ref(siridb->series_map) :
+ imap_vec_pop(q_drop->series_map);
uv_mutex_unlock(&siridb->series_mutex);
- if (q_drop->slist == NULL)
+ if (q_drop->vec == NULL)
{
MEM_ERR_RET
}
else
{
double percent = (double)
- q_drop->slist->len / siridb->series_map->len;
+ q_drop->vec->len / siridb->series_map->len;
if (IS_MASTER &&
- q_drop->slist->len &&
+ q_drop->vec->len &&
(~q_drop->flags & QUERIES_IGNORE_DROP_THRESHOLD) &&
percent >= siridb->drop_threshold)
{
{
QP_ADD_SUCCESS
- q_drop->n = q_drop->slist->len;
+ q_drop->n = q_drop->vec->len;
uv_async_t * next = (uv_async_t *) malloc(sizeof(uv_async_t));
uv_mutex_lock(&siridb->shards_mutex);
- q_drop->shards_list = imap_2slist_ref(siridb->shards);
+ q_drop->shards_list = imap_2vec_ref(siridb->shards);
uv_mutex_unlock(&siridb->shards_mutex);
query->nodes->node->children->next->node;
char username[user_node->len - 1];
- strx_extract_string(username, user_node->str, user_node->len);
+ xstr_extract_string(username, user_node->str, user_node->len);
if (siridb_users_drop_user(
siridb,
if (q_list->props == NULL)
{
- q_list->props = slist_new(3);
+ q_list->props = vec_new(3);
if (q_list->props == NULL)
{
MEM_ERR_RET
}
- slist_append(q_list->props, &GID_K_POOL);
- slist_append(q_list->props, &GID_K_SERVERS);
- slist_append(q_list->props, &GID_K_SERIES);
+ vec_append(q_list->props, &GID_K_POOL);
+ vec_append(q_list->props, &GID_K_SERVERS);
+ vec_append(q_list->props, &GID_K_SERIES);
qp_add_raw(query->packer, (const unsigned char *) "pool", 4);
qp_add_raw(query->packer, (const unsigned char *) "servers", 7);
qp_add_raw(query->packer, (const unsigned char *) "series", 6);
if (q_list->props == NULL)
{
- q_list->props = slist_new(1);
+ q_list->props = vec_new(1);
if (q_list->props == NULL)
{
MEM_ERR_RET
}
- slist_append(q_list->props, &GID_K_NAME);
+ vec_append(q_list->props, &GID_K_NAME);
qp_add_raw(query->packer, (const unsigned char *) "name", 4);
}
uv_mutex_lock(&siridb->series_mutex);
- q_list->slist = imap_2slist_ref((q_list->series_map == NULL) ?
+ q_list->vec = imap_2vec_ref((q_list->series_map == NULL) ?
siridb->series_map : q_list->series_map);
uv_mutex_unlock(&siridb->series_mutex);
- if (q_list->slist == NULL)
+ if (q_list->vec == NULL)
{
MEM_ERR_RET;
}
if (q_list->props == NULL)
{
- q_list->props = slist_new(5);
+ q_list->props = vec_new(5);
if (q_list->props == NULL)
{
MEM_ERR_RET
}
- slist_append(q_list->props, &GID_K_NAME);
- slist_append(q_list->props, &GID_K_POOL);
- slist_append(q_list->props, &GID_K_VERSION);
- slist_append(q_list->props, &GID_K_ONLINE);
- slist_append(q_list->props, &GID_K_STATUS);
+ vec_append(q_list->props, &GID_K_NAME);
+ vec_append(q_list->props, &GID_K_POOL);
+ vec_append(q_list->props, &GID_K_VERSION);
+ vec_append(q_list->props, &GID_K_ONLINE);
+ vec_append(q_list->props, &GID_K_STATUS);
qp_add_raw(query->packer, (const unsigned char *) "name", 4);
qp_add_raw(query->packer, (const unsigned char *) "pool", 4);
qp_add_raw(query->packer, (const unsigned char *) "version", 7);
.server=siridb->server
};
size_t i;
- slist_t * shards_list;
+ vec_t * shards_list;
uv_mutex_lock(&siridb->shards_mutex);
- shards_list = imap_2slist_ref(siridb->shards);
+ shards_list = imap_2vec_ref(siridb->shards);
uv_mutex_unlock(&siridb->shards_mutex);
if (q_list->props == NULL)
{
- q_list->props = slist_new(5);
+ q_list->props = vec_new(5);
if (q_list->props == NULL)
{
MEM_ERR_RET
}
- slist_append(q_list->props, &GID_K_SID);
- slist_append(q_list->props, &GID_K_POOL);
- slist_append(q_list->props, &GID_K_SERVER);
- slist_append(q_list->props, &GID_K_START);
- slist_append(q_list->props, &GID_K_END);
+ vec_append(q_list->props, &GID_K_SID);
+ vec_append(q_list->props, &GID_K_POOL);
+ vec_append(q_list->props, &GID_K_SERVER);
+ vec_append(q_list->props, &GID_K_START);
+ vec_append(q_list->props, &GID_K_END);
qp_add_raw(query->packer, (const unsigned char *) "sid", 3);
qp_add_raw(query->packer, (const unsigned char *) "pool", 4);
qp_add_raw(query->packer, (const unsigned char *) "server", 6);
siridb_shard_decref(vshard.shard);
}
- slist_free(shards_list);
+ vec_free(shards_list);
if (IS_MASTER && q_list->limit)
{
siridb_t * siridb = query->client->siridb;
llist_node_t * node = siridb->users->first;
- slist_t * props = ((query_list_t *) query->data)->props;
+ vec_t * props = ((query_list_t *) query->data)->props;
cexpr_cb_t cb = (cexpr_cb_t) siridb_user_cexpr_cb;
query_list_t * q_list = (query_list_t *) query->data;
cexpr_t * where_expr = q_list->where_expr;
if (q_select->where_expr != NULL)
{
- /* we transform the references from imap to slist */
- q_select->slist = imap_slist_pop(q_select->series_map);
+ /* we transform the references from imap to vec */
+ q_select->vec = imap_vec_pop(q_select->series_map);
- if (q_select->slist == NULL)
+ if (q_select->vec == NULL)
{
MEM_ERR_RET
}
{
if (q_select->merge_as != NULL)
{
- slist_t * plist = slist_new(SLIST_DEFAULT_SIZE);
+ vec_t * plist = vec_new(VEC_DEFAULT_SIZE);
if (plist == NULL || ct_add(
q_select->result,
sprintf(query->err_msg,
"Error while merging points. Make sure the "
"destination series name is valid.");
- slist_free(plist);
+ vec_free(plist);
siridb_query_send_error(handle, CPROTO_ERR_QUERY);
return;
}
siridb_query_send_error(handle, CPROTO_ERR_QUERY);
return;
}
- q_select->slist = imap_2slist_ref(q_select->series_map);
+ q_select->vec = imap_2vec_ref(q_select->series_map);
- if (q_select->slist == NULL)
+ if (q_select->vec == NULL)
{
MEM_ERR_RET
}
}
char address[node->len - 1];
- strx_extract_string(address, node->str, node->len);
+ xstr_extract_string(address, node->str, node->len);
int rc;
rc = siridb_server_update_address(siridb, server, address, server->port);
cleri_node_t * node = query->nodes->node->children->next->next->node;
- double drop_threshold = strx_to_double(node->str, node->len);
+ double drop_threshold = xstr_to_double(node->str, node->len);
if (drop_threshold < 0.0 || drop_threshold > 1.0)
{
cleri_node_t * node = query->nodes->node->children->next->next->node;
- uint64_t limit = strx_to_uint64(node->str, node->len);
+ uint64_t limit = xstr_to_uint64(node->str, node->len);
if (limit < 1000 || limit >= 4294967296)
{
}
- uint64_t port = strx_to_uint64(node->str, node->len);
+ uint64_t port = xstr_to_uint64(node->str, node->len);
if (port > 65535)
{
cleri_node_t * node = query->nodes->node->children->next->next->node;
- uint64_t limit = strx_to_uint64(node->str, node->len);
+ uint64_t limit = xstr_to_uint64(node->str, node->len);
if (limit < 1 || limit >= 4294967296)
{
MASTER_CHECK_ACCESSIBLE(siridb)
char timezone[node->len - 1];
- strx_extract_string(timezone, node->str, node->len);
+ xstr_extract_string(timezone, node->str, node->len);
iso8601_tz_t new_tz = iso8601_tz(timezone);
query_count_t * q_count = (query_count_t *) query->data;
uint8_t async_more = 0;
- size_t index_end = q_count->slist_index + MAX_ITERATE_COUNT;
+ size_t index_end = q_count->vec_index + MAX_ITERATE_COUNT;
- if (index_end >= q_count->slist->len)
+ if (index_end >= q_count->vec->len)
{
- index_end = q_count->slist->len;
+ index_end = q_count->vec->len;
}
else
{
async_more = 1;
}
- for (; q_count->slist_index < index_end; q_count->slist_index++)
+ for (; q_count->vec_index < index_end; q_count->vec_index++)
{
- series = (siridb_series_t *) q_count->slist->data[q_count->slist_index];
+ series = (siridb_series_t *) q_count->vec->data[q_count->vec_index];
q_count->n += cexpr_run(
q_count->where_expr,
(cexpr_cb_t) siridb_series_cexpr_cb,
query_count_t * q_count = (query_count_t *) query->data;
uint8_t async_more = 0;
- size_t index_end = q_count->slist_index + MAX_ITERATE_COUNT;
+ size_t index_end = q_count->vec_index + MAX_ITERATE_COUNT;
- if (index_end >= q_count->slist->len)
+ if (index_end >= q_count->vec->len)
{
- index_end = q_count->slist->len;
+ index_end = q_count->vec->len;
}
else
{
async_more = 1;
}
- for (; q_count->slist_index < index_end; q_count->slist_index++)
+ for (; q_count->vec_index < index_end; q_count->vec_index++)
{
- series = (siridb_series_t *) q_count->slist->data[q_count->slist_index];
+ series = (siridb_series_t *) q_count->vec->data[q_count->vec_index];
if (cexpr_run(
q_count->where_expr,
siridb_series_t * series;
uint8_t async_more = 0;
- size_t index_end = q_drop->slist_index + MAX_ITERATE_COUNT;
+ size_t index_end = q_drop->vec_index + MAX_ITERATE_COUNT;
- if (index_end >= q_drop->slist->len)
+ if (index_end >= q_drop->vec->len)
{
- index_end = q_drop->slist->len;
+ index_end = q_drop->vec->len;
}
else
{
uv_mutex_lock(&siridb->series_mutex);
- for (; q_drop->slist_index < index_end; q_drop->slist_index++)
+ for (; q_drop->vec_index < index_end; q_drop->vec_index++)
{
- series = (siridb_series_t *) q_drop->slist->data[q_drop->slist_index];
+ series = (siridb_series_t *) q_drop->vec->data[q_drop->vec_index];
siridb_series_drop(siridb, series);
siridb_series_decref(series);
}
uv_mutex_unlock(&siridb->series_mutex);
/* flush dropped file change to disk */
- if (q_drop->slist->len)
+ if (q_drop->vec->len)
{
siridb_series_flush_dropped(siridb);
}
if (q_drop->shards_list->len)
{
- siridb_shard_t * shard = (siridb_shard_t *) slist_pop(
+ siridb_shard_t * shard = (siridb_shard_t *) vec_pop(
q_drop->shards_list);
siridb_shard_drop(
cexpr_t * where_expr = q_wrapper->where_expr;
uint8_t async_more = 0;
siridb_series_t * series;
- size_t index_end = q_wrapper->slist_index + MAX_ITERATE_COUNT;
+ size_t index_end = q_wrapper->vec_index + MAX_ITERATE_COUNT;
- if (index_end >= q_wrapper->slist->len)
+ if (index_end >= q_wrapper->vec->len)
{
- index_end = q_wrapper->slist->len;
+ index_end = q_wrapper->vec->len;
}
else
{
async_more = 1;
}
- for (; q_wrapper->slist_index < index_end; q_wrapper->slist_index++)
+ for (; q_wrapper->vec_index < index_end; q_wrapper->vec_index++)
{
series = (siridb_series_t *)
- q_wrapper->slist->data[q_wrapper->slist_index];
+ q_wrapper->vec->data[q_wrapper->vec_index];
if (cexpr_run(
where_expr,
else
{
/* free the s-list object and reset index */
- slist_free(q_wrapper->slist);
+ vec_free(q_wrapper->vec);
- q_wrapper->slist = NULL;
- q_wrapper->slist_index = 0;
+ q_wrapper->vec = NULL;
+ q_wrapper->vec_index = 0;
/* cleanup where statement since we do not need it anymore */
cexpr_free(q_wrapper->where_expr);
{
siridb_query_t * query = (siridb_query_t *) handle->data;
query_list_t * q_list = (query_list_t *) query->data;
- slist_t * props = q_list->props;
+ vec_t * props = q_list->props;
cexpr_t * where_expr = q_list->where_expr;
uint8_t async_more = 0;
siridb_series_t * series;
size_t i;
- size_t index_end = q_list->slist_index + MAX_ITERATE_COUNT;
+ size_t index_end = q_list->vec_index + MAX_ITERATE_COUNT;
- if (index_end >= q_list->slist->len)
+ if (index_end >= q_list->vec->len)
{
- index_end = q_list->slist->len;
+ index_end = q_list->vec->len;
}
else
{
async_more = 1;
}
- for (; q_list->limit && q_list->slist_index < index_end;
- q_list->slist_index++)
+ for (; q_list->limit && q_list->vec_index < index_end;
+ q_list->vec_index++)
{
- series = (siridb_series_t *) q_list->slist->data[q_list->slist_index];
+ series = (siridb_series_t *) q_list->vec->data[q_list->vec_index];
if (where_expr == NULL || cexpr_run(
where_expr,
siridb_points_t * aggr_points;
int required_shard = 0;
- for (; q_select->slist_index < q_select->slist->len;
- ++q_select->slist_index)
+ for (; q_select->vec_index < q_select->vec->len;
+ ++q_select->vec_index)
{
if (required_shard > MAX_BATCH_REQUIRE_SHARD)
{
}
series = (siridb_series_t *)
- q_select->slist->data[q_select->slist_index];
+ q_select->vec->data[q_select->vec_index];
/*
* We must decrement the ref count immediately since the index is
* incremented by one. The series will not be freed since at least
}
else
{
- slist_t ** plist;
+ vec_t ** plist;
name = siridb_presuf_name(
q_select->presuf,
q_select->merge_as,
strlen(q_select->merge_as));
- plist = (slist_t **) ct_getaddr(q_select->result, name);
+ plist = (vec_t **) ct_getaddr(q_select->result, name);
if ( name == NULL ||
plist == NULL ||
- slist_append_safe(plist, points))
+ vec_append_safe(plist, points))
{
sprintf(query->err_msg, "Error adding points to map.");
siridb_points_free(points);
siridb_aggregate_list_free(q_select->alist);
q_select->alist = NULL;
- slist_free(q_select->slist);
- q_select->slist = NULL;
- q_select->slist_index = 0;
+ vec_free(q_select->vec);
+ q_select->vec = NULL;
+ q_select->vec_index = 0;
SIRIPARSER_ASYNC_NEXT_NODE
}
}
series = (siridb_series_t *)
- q_select->slist->data[q_select->slist_index];
+ q_select->vec->data[q_select->vec_index];
/*
* We must decrement the ref count immediately since we now update the
*/
siridb_series_decref(series);
- if ((++q_select->slist_index) < q_select->slist->len)
+ if ((++q_select->vec_index) < q_select->vec->len)
{
async_more = 1;
}
}
else
{
- slist_t ** plist;
+ vec_t ** plist;
name = siridb_presuf_name(
q_select->presuf,
q_select->merge_as,
strlen(q_select->merge_as));
- plist = (slist_t **) ct_getaddr(q_select->result, name);
+ plist = (vec_t **) ct_getaddr(q_select->result, name);
if ( name == NULL ||
plist == NULL ||
- slist_append_safe(plist, points))
+ vec_append_safe(plist, points))
{
sprintf(query->err_msg, "Error adding points to map.");
siridb_points_free(points);
siridb_aggregate_list_free(q_select->alist);
q_select->alist = NULL;
- slist_free(q_select->slist);
- q_select->slist = NULL;
- q_select->slist_index = 0;
+ vec_free(q_select->vec);
+ q_select->vec = NULL;
+ q_select->vec_index = 0;
SIRIPARSER_ASYNC_NEXT_NODE
}
query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
uint8_t async_more = 0;
siridb_series_t * series;
- size_t index_end = q_wrapper->slist_index + MAX_ITERATE_COUNT;
+ size_t index_end = q_wrapper->vec_index + MAX_ITERATE_COUNT;
- if (index_end >= q_wrapper->slist->len)
+ if (index_end >= q_wrapper->vec->len)
{
- index_end = q_wrapper->slist->len;
+ index_end = q_wrapper->vec->len;
}
else
{
int pcre_exec_ret;
- for (; q_wrapper->slist_index < index_end; q_wrapper->slist_index++)
+ for (; q_wrapper->vec_index < index_end; q_wrapper->vec_index++)
{
series = (siridb_series_t *)
- q_wrapper->slist->data[q_wrapper->slist_index];
+ q_wrapper->vec->data[q_wrapper->vec_index];
pcre_exec_ret = pcre2_match(
q_wrapper->regex,
else
{
/* free the s-list object and reset index */
- slist_free(q_wrapper->slist);
+ vec_free(q_wrapper->vec);
pcre2_code_free(q_wrapper->regex);
pcre2_match_data_free(q_wrapper->match_data);
q_wrapper->regex = NULL;
q_wrapper->match_data = NULL;
- q_wrapper->slist = NULL;
- q_wrapper->slist_index = 0;
+ q_wrapper->vec = NULL;
+ q_wrapper->vec_index = 0;
if (q_wrapper->update_cb != NULL)
{
*
* Make sure to run siri_async_incref() on the handle
*/
-static void on_alter_xxx_response(slist_t * promises, uv_async_t * handle)
+static void on_alter_xxx_response(vec_t * promises, uv_async_t * handle)
{
ON_PROMISES
*
* Make sure to run siri_async_incref() on the handle
*/
-static void on_count_xxx_response(slist_t * promises, uv_async_t * handle)
+static void on_count_xxx_response(vec_t * promises, uv_async_t * handle)
{
ON_PROMISES
*
* Make sure to run siri_async_incref() on the handle
*/
-static void on_drop_series_response(slist_t * promises, uv_async_t * handle)
+static void on_drop_series_response(vec_t * promises, uv_async_t * handle)
{
ON_PROMISES
*
* Make sure to run siri_async_incref() on the handle
*/
-static void on_drop_shards_response(slist_t * promises, uv_async_t * handle)
+static void on_drop_shards_response(vec_t * promises, uv_async_t * handle)
{
ON_PROMISES
*
* Make sure to run siri_async_incref() on the handle
*/
-static void on_groups_response(slist_t * promises, uv_async_t * handle)
+static void on_groups_response(vec_t * promises, uv_async_t * handle)
{
ON_PROMISES
*
* Make sure to run siri_async_incref() on the handle
*/
-static void on_list_xxx_response(slist_t * promises, uv_async_t * handle)
+static void on_list_xxx_response(vec_t * promises, uv_async_t * handle)
{
ON_PROMISES
*
* Make sure to run siri_async_incref() on the handle
*/
-static void on_select_response(slist_t * promises, uv_async_t * handle)
+static void on_select_response(vec_t * promises, uv_async_t * handle)
{
ON_PROMISES
*
* Make sure to run siri_async_incref() on the handle
*/
-static void on_update_xxx_response(slist_t * promises, uv_async_t * handle)
+static void on_update_xxx_response(vec_t * promises, uv_async_t * handle)
{
ON_PROMISES
static int items_select_master_merge(
const char * name,
size_t len,
- slist_t * plist,
+ vec_t * plist,
uv_async_t * handle)
{
siridb_query_t * query = (siridb_query_t *) handle->data;
}
break;
case 1:
- points = slist_pop(plist);
+ points = vec_pop(plist);
break;
default:
points = siridb_points_merge(plist, query->err_msg);
static int items_select_other_merge(
const char * name,
size_t len,
- slist_t * plist,
+ vec_t * plist,
uv_async_t * handle)
{
size_t i;
qp_is_raw_term(qp_name) &&
qp_is_array(qp_next(unpacker, NULL)))
{
- slist_t ** plist = (slist_t **) ct_getaddr(
+ vec_t ** plist = (vec_t **) ct_getaddr(
q_select->result,
(const char *) qp_name->via.raw);
memcpy(points->data, qp_points->via.raw, qp_points->len);
}
- if (slist_append_safe(plist, points))
+ if (vec_append_safe(plist, points))
{
siridb_points_free(points);
}
siridb_query_t * query = (siridb_query_t *) handle->data;
cexpr_t * where_expr = ((query_list_t *) query->data)->where_expr;
cexpr_cb_t cb = (cexpr_cb_t) siridb_group_cexpr_cb;
- slist_t * props = ((query_list_t *) query->data)->props;
+ vec_t * props = ((query_list_t *) query->data)->props;
if (where_expr == NULL || cexpr_run(where_expr, cb, group))
{
if (q_list->props == NULL)
{
- q_list->props = slist_new(1);
+ q_list->props = vec_new(1);
if (q_list->props == NULL)
{
MEM_ERR_RET
}
- slist_append(q_list->props, &GID_K_NAME);
+ vec_append(q_list->props, &GID_K_NAME);
qp_add_raw(query->packer, (const unsigned char *) "name", 4);
}
/*
- * lookup.c - SiriDB Pool lookup.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 29-07-2016
- *
+ * lookup.c - Find and assign to which pool series belong.
*/
#include <siri/db/lookup.h>
#include <siri/err.h>
/*
* median.c - Calculate median, median high and median low.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 16-04-2016
- *
*/
-
-
#include <siri/db/median.h>
#include <siri/db/points.h>
#include <stdbool.h>
/*
* misc.c - Miscellaneous functions used by SiriDB.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 18-08-2016
- *
*/
#include <siri/db/misc.h>
#include <stdlib.h>
/*
- * node.c - contains logic for cleri nodes which we need to parse.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-03-2016
- *
+ * nodes.c - Contains logic for cleri nodes which we need to parse.
*/
#include <logger/logger.h>
#include <siri/db/nodes.h>
/*
- * pcache.h - Points structure with notion or its size
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-10-2016
- *
+ * pcache.c - Points structure with notion of its size.
*/
-
#include <assert.h>
#include <siri/db/pcache.h>
#include <siri/err.h>
/*
* points.c - Array object for points.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 04-04-2016
- *
*/
#include <siri/db/points.h>
#include <logger/logger.h>
#include <siri/err.h>
#include <unistd.h>
#include <string.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
#define MAX_ITERATE_MERGE_COUNT 1000
#define POINTS_MAX_QSORT 250000
uint64_t * start_ts,
uint64_t * end_ts,
uint8_t has_overlap);
-static void POINTS_sort_while_merge(slist_t * plist, siridb_points_t * points);
-static void POINTS_merge_and_sort(slist_t * plist, siridb_points_t * points);
+static void POINTS_sort_while_merge(vec_t * plist, siridb_points_t * points);
+static void POINTS_merge_and_sort(vec_t * plist, siridb_points_t * points);
static void POINTS_simple_sort(siridb_points_t * points);
static inline int POINTS_compare(const void * a, const void * b);
-static void POINTS_highest_and_merge(slist_t * plist, siridb_points_t * points);
+static void POINTS_highest_and_merge(vec_t * plist, siridb_points_t * points);
static size_t POINTS_strlen_check_ascii(const char * str, uint8_t * is_ascii);
static void POINTS_output_literal(
size_t len,
* (err_msg is set when an error has occurred)
* Use this function only when having at least two 'series' in the list.
*/
-siridb_points_t * siridb_points_merge(slist_t * plist, char * err_msg)
+siridb_points_t * siridb_points_merge(vec_t * plist, char * err_msg)
{
assert (plist->len >= 2);
siridb_points_t * points;
* list length to 0. We do have to restore the points length since
* this is decremented by one.
*/
- points = (siridb_points_t *) slist_pop(plist);
+ points = (siridb_points_t *) vec_pop(plist);
points->len++;
return points;
}
{
size_t slen;
points->data[points->len].ts = *tpt;
- points->data[points->len].val.str = strx_dup(cpt, &slen);
+ points->data[points->len].val.str = xstr_dup(cpt, &slen);
cpt += slen + 1;
}
return 0;
* This merge method works best when having both a lot of series and having
* any number of points for each series.
*/
-static void POINTS_highest_and_merge(slist_t * plist, siridb_points_t * points)
+static void POINTS_highest_and_merge(vec_t * plist, siridb_points_t * points)
{
siridb_points_t ** m = NULL;
size_t i, n, l = 0;
* This merge method works best for only a few series with possible a lot
* of points.
*/
-static void POINTS_sort_while_merge(slist_t * plist, siridb_points_t * points)
+static void POINTS_sort_while_merge(vec_t * plist, siridb_points_t * points)
{
siridb_points_t ** m;
size_t i, n;
* This merge method works best when having a lot of series with only one point
* or when the total number of points it not so high.
*/
-static void POINTS_merge_and_sort(slist_t * plist, siridb_points_t * points)
+static void POINTS_merge_and_sort(vec_t * plist, siridb_points_t * points)
{
siridb_points_t ** m;
size_t i, n;
/*
- * pool.c - Generate pool lookup.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 25-03-2016
- *
+ * pool.c - SiriDB pool containing one or two servers.
*/
-
#include <assert.h>
#include <logger/logger.h>
#include <siri/db/pool.h>
/*
- * pools.c - Generate pools lookup.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 04-05-2016
+ * pools.c - Collection of pools.
*/
-
#include <assert.h>
#include <llist/llist.h>
#include <logger/logger.h>
"Cannot send package to pool '%u' "
"(no accessible server found)",
pid);
- slist_append(promises->promises, NULL);
+ vec_append(promises->promises, NULL);
}
}
/*
* This function will send a package to one accessible server in the pools
- * provided by the 'slist'. The promises call-back function should be
+ * provided by the 'vec'. The promises call-back function should be
* used to check if the package has been send successfully to all pools.
*
- * The 'slist' can be destroyed after this function has returned.
+ * The 'vec' can be destroyed after this function has returned.
*
* This function can raise a SIGNAL when allocation errors occur.
*
* will always be destroyed.
*/
void siridb_pools_send_pkg_2some(
- slist_t * slist,
+ vec_t * vec,
sirinet_pkg_t * pkg,
uint64_t timeout,
sirinet_promises_cb cb,
int flags)
{
sirinet_promises_t * promises =
- sirinet_promises_new(slist->len, cb, data, pkg);
+ sirinet_promises_new(vec->len, cb, data, pkg);
if (promises == NULL)
{
siridb_pool_t * pool;
size_t i;
- for (i = 0; i < slist->len; i++)
+ for (i = 0; i < vec->len; i++)
{
- pool = slist->data[i];
+ pool = vec->data[i];
if (siridb_pool_send_pkg(
pool,
log_debug(
"Cannot send package to at least on pool "
"(no accessible server found)");
- slist_append(promises->promises, NULL);
+ vec_append(promises->promises, NULL);
}
}
/*
* presuf.c - Prefix and Suffix store.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-08-2016
- *
*/
#include <assert.h>
#include <logger/logger.h>
#include <siri/grammar/grammar.h>
#include <stdio.h>
#include <stdlib.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
#include <string.h>
siridb_presuf_t * PRESUF_add(siridb_presuf_t ** presuf);
if (nps->prefix != NULL)
{
/* not critical if suffix is still NULL */
- nps->len += strx_extract_string(
+ nps->len += xstr_extract_string(
nps->prefix,
ps_children->next->node->str,
ps_children->next->node->len);
if (nps->suffix != NULL)
{
/* not critical if suffix is still NULL */
- nps->len += strx_extract_string(
+ nps->len += xstr_extract_string(
nps->suffix,
ps_children->next->node->str,
ps_children->next->node->len);
/*
* props.c - Functions to return SiriDB properties.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 17-03-2016
- *
*/
#include <assert.h>
#include <logger/logger.h>
/*
- * queries.c - Querie helpers for listener
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 03-05-2016
- *
+ * queries.c - Query helpers for listener.
*/
#include <assert.h>
#include <logger/logger.h>
q->flags = 0; \
q->series_map = NULL; \
q->series_tmp = NULL; \
-q->slist = NULL; \
-q->slist_index = 0; \
+q->vec = NULL; \
+q->vec_index = 0; \
q->pmap = NULL; \
q->update_cb = NULL; \
q->where_expr = NULL; \
q->series_tmp, \
(imap_free_cb) &siridb__series_decref); \
} \
-if (q->slist != NULL) \
+if (q->vec != NULL) \
{ \
siridb_series_t * series; \
- for (; q->slist_index < q->slist->len; q->slist_index++) \
+ for (; q->vec_index < q->vec->len; q->vec_index++) \
{ \
- series = (siridb_series_t *) q->slist->data[q->slist_index]; \
+ series = (siridb_series_t *) q->vec->data[q->vec_index]; \
siridb_series_decref(series); \
} \
- slist_free(q->slist); \
+ vec_free(q->vec); \
} \
if (q->where_expr != NULL) \
{ \
free(q); \
siridb_query_free(handle);
-static void QUERIES_free_merge_result(slist_t * plist);
+static void QUERIES_free_merge_result(vec_t * plist);
query_select_t * query_select_new(void)
{
siridb_shard_t * shard;
while (q_drop->shards_list->len)
{
- shard = (siridb_shard_t *) slist_pop(q_drop->shards_list);
+ shard = (siridb_shard_t *) vec_pop(q_drop->shards_list);
siridb_shard_decref(shard);
}
- slist_free(q_drop->shards_list);
+ vec_free(q_drop->shards_list);
}
QUERIES_FREE(q_drop, handle)
if (q_list->props != NULL)
{
- slist_free(q_list->props);
+ vec_free(q_list->props);
}
QUERIES_FREE(q_list, handle)
siridb_query_free(handle);
}
-static void QUERIES_free_merge_result(slist_t * plist)
+static void QUERIES_free_merge_result(vec_t * plist)
{
size_t i;
for (i = 0; i < plist->len; i ++)
/*
* query.c - Responsible for parsing queries.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-03-2016
- *
*/
#include <assert.h>
#include <cleri/cleri.h>
#include <siri/net/pkg.h>
#include <siri/net/clserver.h>
#include <siri/siri.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
#include <string.h>
#include <sys/time.h>
#include <siri/err.h>
case SIRIDB_QUERY_FWD_SERVERS:
pkg->tp = BPROTO_QUERY_SERVER;
{
- slist_t * servers = siridb_servers_other2slist(siridb);
+ vec_t * servers = siridb_servers_other2vec(siridb);
if (servers != NULL)
{
siridb_servers_send_pkg(
SIRIDB_FWD_SERVERS_TIMEOUT,
cb,
handle);
- slist_free(servers);
+ vec_free(servers);
}
else
{
handle->data)->data)->pmap != NULL);
pkg->tp = BPROTO_QUERY_SERVER;
{
- slist_t * borrow_list = imap_slist(((query_select_t *) (
+ vec_t * borrow_list = imap_vec(((query_select_t *) (
(siridb_query_t *) handle->data)->data)->pmap);
if (borrow_list != NULL)
{
- /* if slist is NULL, a signal is raised */
+ /* if vec is NULL, a signal is raised */
siridb_pools_send_pkg_2some(
borrow_list,
pkg,
char datestr[node->len - 1];
/* extract date string */
- strx_extract_string(datestr, node->str, node->len);
+ xstr_extract_string(datestr, node->str, node->len);
/* get timestamp from date string */
int64_t ts = iso8601_parse_date(datestr, walker->siridb->tz);
/*
- * re.c - Helpers for regular expressions
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 04-08-2016
- *
+ * re.c - Helpers for regular expressions.
*/
#include <assert.h>
#include <siri/db/db.h>
/*
* reindex.c - SiriDB Re-index.
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 27-07-2016
- *
* Differences while re-indexing:
*
* - Group information like number of series will be updated at a lower
/*
* replicate.c - Replicate SiriDB.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- *
- * changes
- * - initial version, 11-07-2016
- *
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
/*
- * series.c - Series
+ * series.c - SiriDB Time Series.
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 29-03-2016
*
* Info siridb->series_mutex:
*
siridb_points_free(series->buffer);
if (series->flags & SIRIDB_SERIES_IS_DROPPED)
{
- slist_append_safe(
+ vec_append_safe(
&series->siridb->buffer->empty,
(void *) series->bf_offset);
}
/*
- * server.c - SiriDB Server.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 17-03-2016
- *
+ * server.c - Each SiriDB database has at least one server.
*/
#include <assert.h>
#include <logger/logger.h>
#include <siri/net/tcp.h>
#include <siri/siri.h>
#include <siri/version.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
#include <string.h>
#define SIRIDB_SERVERS_FN "servers.dat"
case CLERI_TP_CHOICE: /* server name */
{
char name[server_node->len - 1];
- strx_extract_string(name, server_node->str, server_node->len);
+ xstr_extract_string(name, server_node->str, server_node->len);
server = siridb_servers_by_name(siridb->servers, name);
}
break;
/*
- * servers.c - SiriDB Servers.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-06-2016
- *
+ * servers.c - Collection of SiriDB servers.
*/
#include <assert.h>
#include <llist/llist.h>
*
* In case of an error, NULL is returned.
*/
-slist_t * siridb_servers_other2slist(siridb_t * siridb)
+vec_t * siridb_servers_other2vec(siridb_t * siridb)
{
siridb_server_t * server;
- slist_t * servers = slist_new(siridb->servers->len - 1);
+ vec_t * servers = vec_new(siridb->servers->len - 1);
llist_node_t * node;
if (servers == NULL)
server = node->data;
if (server != siridb->server)
{
- slist_append(servers, server);
+ vec_append(servers, server);
}
}
* using the arguments (NULL, data).
*/
void siridb_servers_send_pkg(
- slist_t * servers,
+ vec_t * servers,
sirinet_pkg_t * pkg,
uint64_t timeout,
sirinet_promises_cb cb,
log_critical(
"Allocation error while trying to send a package "
"to '%s'", server->name);
- slist_append(promises->promises, NULL);
+ vec_append(promises->promises, NULL);
}
}
else
{
log_debug("Cannot send package to '%s' (server is offline)",
server->name);
- slist_append(promises->promises, NULL);
+ vec_append(promises->promises, NULL);
}
}
{
siridb_query_t * query = handle->data;
query_list_t * qlist = query->data;
- slist_t * props = qlist->props;
+ vec_t * props = qlist->props;
siridb_t * siridb = query->client->siridb;
cexpr_t * where_expr = qlist->where_expr;
size_t i;
/*
- * shard.c - SiriDB Shard.
-
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 04-04-2016
- *
+ * shard.c - SiriDB shard file.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#include <siri/err.h>
#include <siri/file/pointer.h>
#include <siri/siri.h>
-#include <slist/slist.h>
+#include <vec/vec.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
/* max read buffer size used for reading from index file */
{
size_t slen;
qp_via_t v;
- v.str = strx_dup(cpt, &slen);
+ v.str = xstr_dup(cpt, &slen);
cpt += slen + 1;
uint64_t ts = *tpt;
siridb_points_add_point(points, &ts, &v);
{
size_t slen;
points->data[points->len].ts = *tpt;
- points->data[points->len].val.str = strx_dup(cpt, &slen);
+ points->data[points->len].val.str = xstr_dup(cpt, &slen);
cpt += slen + 1;
}
}
{
size_t slen;
qp_via_t v;
- v.str = strx_dup(cpt, &slen);
+ v.str = xstr_dup(cpt, &slen);
cpt += slen + 1;
siridb_points_add_point(points, tpt, &v);
}
{
size_t slen;
points->data[points->len].ts = *tpt;
- points->data[points->len].val.str = strx_dup(cpt, &slen);
+ points->data[points->len].val.str = xstr_dup(cpt, &slen);
cpt += slen + 1;
}
}
uv_mutex_lock(&siridb->series_mutex);
- slist_t * slist = imap_2slist_ref(siridb->series_map);
+ vec_t * vec = imap_2vec_ref(siridb->series_map);
uv_mutex_unlock(&siridb->series_mutex);
- if (slist == NULL)
+ if (vec == NULL)
{
ERR_ALLOC
return -1;
sleep(1);
- for (i = 0; i < slist->len; i++)
+ for (i = 0; i < vec->len; i++)
{
/* its possible that another database is paused, but we wait anyway */
if (siri.optimize->pause)
siri_optimize_wait();
}
- series = slist->data[i];
+ series = vec->data[i];
if ( !siri_err &&
siri.optimize->status != SIRI_OPTIMIZE_CANCELLED &&
siridb_series_decref(series);
}
- slist_free(slist);
+ vec_free(vec);
if (new_shard->flags & SIRIDB_SHARD_IS_REMOVED)
{
*/
if (optimizing)
{
- slist_t * slist = imap_2slist_ref(siridb->series_map);
+ vec_t * vec = imap_2vec_ref(siridb->series_map);
size_t i;
- if (slist == NULL)
+ if (vec == NULL)
{
ERR_ALLOC
}
- else for (i = 0; i < slist->len; i++)
+ else for (i = 0; i < vec->len; i++)
{
- series = (siridb_series_t *) slist->data[i];
+ series = (siridb_series_t *) vec->data[i];
if (shard->id % siridb->duration_num == series->mask)
{
siridb_series_remove_shard(siridb, series, shard);
siridb_series_decref(series);
}
- slist_free(slist);
+ vec_free(vec);
}
else
{
- slist_t * slist = imap_2slist(siridb->series_map);
+ vec_t * vec = imap_2vec(siridb->series_map);
size_t i;
- if (slist == NULL)
+ if (vec == NULL)
{
ERR_ALLOC
}
- else for (i = 0; i < slist->len; i++)
+ else for (i = 0; i < vec->len; i++)
{
- series = (siridb_series_t *) slist->data[i];
+ series = (siridb_series_t *) vec->data[i];
if (shard->id % siridb->duration_num == series->mask)
{
siridb_series_remove_shard(siridb, series, shard);
}
}
- slist_free(slist);
+ vec_free(vec);
}
if (pop_shard != NULL)
/*
- * shards.c - SiriDB shards.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 04-04-2016
+ * shards.c - Collection of SiriDB shards.
*
* Info shards->mutex:
*
/*
- * tasks.c - SiriDB Error.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 31-10-2016
- *
+ * tasks.c - Counters for info on SiriDB tasks.
*/
#include <siri/db/tasks.h>
#include <timeit/timeit.h>
/*
* time.c - Time- and time precision functions and constants.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 09-03-2016
- *
*/
#include <assert.h>
#include <logger/logger.h>
/*
- * user.c - contains functions for a SiriDB database member.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-03-2016
- *
+ * user.c - Contains functions for a SiriDB database user.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#include <siri/db/users.h>
#include <siri/err.h>
#include <siri/grammar/grammar.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
#include <owcrypt/owcrypt.h>
#include <string.h>
return -1;
}
- if (!strx_is_graph(password))
+ if (!xstr_is_graph(password))
{
if (err_msg != NULL)
{
return 1;
}
- if (!strx_is_graph(name))
+ if (!xstr_is_graph(name))
{
sprintf(err_msg,
"User name contains illegal characters. (only graphical "
/*
- * users.c - contains functions for a SiriDB database members.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 04-05-2016
- *
+ * users.c - Collection of database users.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#include <siri/db/misc.h>
#include <siri/err.h>
#include <stdlib.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
#include <string.h>
#include <time.h>
#include <xpath/xpath.h>
/*
* variance.c - Calculate variance for points.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-08-2016
- *
*/
#include <assert.h>
#include <math.h>
/*
- * walker.h - creates enter and exit nodes
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 13-06-2016
- *
+ * walker.c - Creates enter and exit nodes.
*/
#include <siri/db/walker.h>
#include <siri/err.h>
+/*
+ * err.c - SiriDB Error.
+ */
#include <siri/err.h>
int siri_err = 0;
/*
- * filehandler.c - Filehandler for shard files.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-04-2016
- *
+ * handler.c - File handler for shard files.
*/
#include <logger/logger.h>
#include <siri/err.h>
/*
- * filepointer.h - File-pointer used in combination with file-handler.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-04-2016
- *
+ * pointer.c - File pointer used in combination with file handler.
*/
#include <logger/logger.h>
#include <siri/err.h>
/*
* heartbeat.c - Heart-beat task SiriDB.
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
* There is one and only one heart-beat task thread running for SiriDB. For
* this reason we do not need to parse data but we should only take care for
* locks while writing data.
- *
- * changes
- * - initial version, 17-06-2016
- *
*/
#include <logger/logger.h>
#include <siri/db/server.h>
/*
- * help.c - Help for SiriDB
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 23-09-2016
- *
+ * help.c - Help for SiriDB.
*/
#include <limits.h>
#include <logger/logger.h>
/*
- * bserver.c - Back-end Server SiriDB.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- *
- * changes
- * - initial version, 18-06-2016
- *
+ * bserver.c - Listen to back-end SiriDB Server.
*/
#include <assert.h>
#include <logger/logger.h>
-
/*
- * clserver.c - TCP server for serving client requests.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 09-03-2016
- *
+ * clserver.c - Listen for client requests.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#include <logger/logger.h>
#include <qpack/qpack.h>
#include <siri/siri.h>
-#include <siri/admin/account.h>
-#include <siri/admin/request.h>
+#include <siri/service/account.h>
+#include <siri/service/request.h>
#include <siri/db/access.h>
#include <siri/db/auth.h>
#include <siri/db/insert.h>
sirinet_pkg_t * pkg,
sirinet_clserver_getfile getfile);
static void on_register_server(sirinet_stream_t * client, sirinet_pkg_t * pkg);
-static void on_req_admin(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void on_req_service(sirinet_stream_t * client, sirinet_pkg_t * pkg);
static void CLSERVER_send_server_error(
siridb_t * siridb,
sirinet_stream_t * client,
sirinet_stream_t * client,
sirinet_pkg_t * pkg);
static void CLSERVER_on_register_server_response(
- slist_t * promises,
+ vec_t * promises,
siridb_server_async_t * server_reg);
#define POOL_ERR_MSG \
case CPROTO_REQ_FILE_DATABASE:
on_reqfile(client, pkg, siridb_get_file);
break;
- case CPROTO_REQ_ADMIN:
- on_req_admin(client, pkg);
+ case CPROTO_REQ_SERVICE:
+ on_req_service(client, pkg);
break;
}
}
sirinet_pkg_t * package = NULL;
siridb_server_t * new_server = NULL;
char err_msg[SIRIDB_MAX_SIZE_ERR_MSG];
- slist_t * servers = NULL;
+ vec_t * servers = NULL;
if (siridb->server->flags != SERVER_FLAG_RUNNING)
{
else
{
/* make a copy of the current servers */
- servers = siridb_servers_other2slist(siridb);
+ servers = siridb_servers_other2vec(siridb);
if (servers == NULL)
{
sprintf(err_msg, "Memory allocation error.");
}
/* free the servers or NULL */
- slist_free(servers);
+ vec_free(servers);
}
-static void on_req_admin(sirinet_stream_t * client, sirinet_pkg_t * pkg)
+static void on_req_service(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
qp_unpacker_t unpacker;
qp_packer_t * packer = NULL;
qp_next(&unpacker, &qp_password) == QP_RAW &&
qp_next(&unpacker, &qp_request) == QP_INT64)
{
- tp = (siri_admin_account_check(
+ tp = (siri_service_account_check(
&siri,
&qp_username,
&qp_password,
err_msg)) ?
- CPROTO_ERR_ADMIN
+ CPROTO_ERR_SERVICE
:
- siri_admin_request(
+ siri_service_request(
qp_request.via.int64,
&unpacker,
&qp_username,
package =
(tp == CPROTO_DEFERRED) ? NULL :
- (tp == CPROTO_ERR_ADMIN) ? sirinet_pkg_err(
+ (tp == CPROTO_ERR_SERVICE) ? sirinet_pkg_err(
pkg->pid,
strlen(err_msg),
tp,
err_msg) :
- (tp == CPROTO_ACK_ADMIN_DATA) ? sirinet_packer2pkg(
+ (tp == CPROTO_ACK_SERVICE_DATA) ? sirinet_packer2pkg(
packer,
pkg->pid,
tp) : sirinet_pkg_new(pkg->pid, 0, tp, NULL);
}
else
{
- log_error("Invalid administrative request received.");
+ log_error("Invalid service request received.");
package = sirinet_pkg_new(
pkg->pid,
0,
- CPROTO_ERR_ADMIN_INVALID_REQUEST,
+ CPROTO_ERR_SERVICE_INVALID_REQUEST,
NULL);
}
if (package != NULL)
{
switch (package->tp)
{
- case CPROTO_ERR_ADMIN_INVALID_REQUEST:
+ case CPROTO_ERR_SERVICE_INVALID_REQUEST:
log_warning("Received an invalid manage request.");
break;
- case CPROTO_ERR_ADMIN:
+ case CPROTO_ERR_SERVICE:
log_warning("Error handling manage request: %s", err_msg);
break;
}
* Typedef: sirinet_promises_cb
*/
static void CLSERVER_on_register_server_response(
- slist_t * promises,
+ vec_t * promises,
siridb_server_async_t * server_reg)
{
if (promises != NULL)
+/*
+ * pipe.c - Named Pipe support.
+ */
#include <assert.h>
#include <string.h>
#include <stdlib.h>
/*
* pkg.c - SiriDB Package type.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 18-06-2016
- *
*/
#include <assert.h>
#include <logger/logger.h>
/*
- * promise.c - Promise SiriDB.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- *
- * changes
- * - initial version, 23-06-2016
- *
+ * promise.c - Promise used for sending to data to SiriDB servers.
*/
#include <assert.h>
#include <logger/logger.h>
/*
- * promises.c - Promises SiriDB.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- *
- * changes
- * - initial version, 13-07-2016
- *
+ * promises.c - Collection for promised.
*/
#include <assert.h>
#include <logger/logger.h>
promises->cb = cb;
promises->data = data;
- promises->promises = slist_new(size);
+ promises->promises = vec_new(size);
promises->pkg = pkg;
if (promises->promises == NULL)
* This function can be used to free promises with data. It assumes
* data simple can be destroyed with simple calling free().
*/
-void sirinet_promises_llist_free(slist_t * promises)
+void sirinet_promises_llist_free(vec_t * promises)
{
sirinet_promise_t * promise;
size_t i;
promise->data = (void *) sirinet_pkg_dup(pkg);
}
- slist_append(promises->promises, (void *) promise);
+ vec_append(promises->promises, (void *) promise);
SIRINET_PROMISES_CHECK(promises)
}
/*
- * protocol.c - Protocol for SiriDB.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 01-08-2016
- *
+ * protocol.c - Protocol definitions for SiriDB.
*/
#include <siri/net/protocol.h>
#include <stdio.h>
case CPROTO_REQ_FILE_DATABASE: return "CPROTO_REQ_FILE_DATABASE";
/* end internal usage */
- case CPROTO_REQ_ADMIN: return "CPROTO_REQ_ADMIN";
+ case CPROTO_REQ_SERVICE: return "CPROTO_REQ_SERVICE";
default:
sprintf(protocol_str, "CPROTO_CLIENT_TYPE_UNKNOWN (%d)", n);
case CPROTO_RES_ACK: return "CPROTO_RES_ACK";
case CPROTO_RES_FILE: return "CPROTO_RES_FILE";
- case CPROTO_ACK_ADMIN: return "CPROTO_ACK_ADMIN";
- case CPROTO_ACK_ADMIN_DATA: return "CPROTO_ACK_ADMIN_DATA";
+ case CPROTO_ACK_SERVICE: return "CPROTO_ACK_SERVICE";
+ case CPROTO_ACK_SERVICE_DATA: return "CPROTO_ACK_SERVICE_DATA";
case CPROTO_ERR_MSG: return "CPROTO_ERR_MSG";
case CPROTO_ERR_QUERY: return "CPROTO_ERR_QUERY";
case CPROTO_ERR_AUTH_CREDENTIALS: return "CPROTO_ERR_AUTH_CREDENTIALS";
case CPROTO_ERR_AUTH_UNKNOWN_DB: return "CPROTO_ERR_AUTH_UNKNOWN_DB";
case CPROTO_ERR_FILE: return "CPROTO_ERR_FILE";
- case CPROTO_ERR_ADMIN: return "CPROTO_ERR_ADMIN";
- case CPROTO_ERR_ADMIN_INVALID_REQUEST: return "CPROTO_ERR_ADMIN_INVALID_REQUEST";
+ case CPROTO_ERR_SERVICE: return "CPROTO_ERR_SERVICE";
+ case CPROTO_ERR_SERVICE_INVALID_REQUEST: return "CPROTO_ERR_SERVICE_INVALID_REQUEST";
default:
sprintf(protocol_str, "CPROTO_SERVER_TYPE_UNKNOWN (%d)", n);
return protocol_str;
/*
- * stream.c - Handle Stream request.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 09-03-2016
- *
+ * stream.c - For handling streams.
*/
#include <assert.h>
#include <logger/logger.h>
-#include <siri/admin/client.h>
+#include <siri/service/client.h>
#include <siri/err.h>
#include <siri/net/protocol.h>
#include <siri/net/stream.h>
}
break;
case STREAM_TCP_MANAGE: /* a server manage connection */
- siri_admin_client_free((siri_admin_client_t *) client->origin);
+ siri_service_client_free((siri_service_client_t *) client->origin);
siri.client = NULL;
break;
}
/*
- * tcp.c - Handle TCP request.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 09-03-2016
- *
+ * tcp.c - TCP support.
*/
#include <siri/net/tcp.h>
#include <stdlib.h>
/*
* optimize.c - Optimize task SiriDB.
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
* There is one and only one optimize task thread running for SiriDB. For this
* reason we do not need to parse data but we should only take care for locks
* while writing data.
*
- *
* Thread debugging:
* log_debug("getpid: %d - pthread_self: %lu",getpid(), pthread_self());
*
- * changes
- * - initial version, 09-05-2016
- *
*/
#include <assert.h>
#include <logger/logger.h>
#include <siri/db/shard.h>
#include <siri/optimize.h>
#include <siri/siri.h>
-#include <slist/slist.h>
+#include <vec/vec.h>
#include <unistd.h>
static siri_optimize_t optimize = {
};
static void OPTIMIZE_work(uv_work_t * work);
-static void OPTIMIZE_cleanup(slist_t * slsiridb);
+static void OPTIMIZE_cleanup(vec_t * slsiridb);
static void OPTIMIZE_work_finish(uv_work_t * work, int status);
static void OPTIMIZE_cb(uv_timer_t * handle);
* Optimize Thread
*/
- slist_t * slsiridb;
- slist_t * slshards;
+ vec_t * slsiridb;
+ vec_t * slshards;
siridb_t * siridb;
siridb_shard_t * shard;
uint8_t c = siri.cfg->shard_compression;
uv_mutex_lock(&siri.siridb_mutex);
- slsiridb = llist2slist(siri.siridb_list);
+ slsiridb = llist2vec(siri.siridb_list);
if (slsiridb != NULL)
{
for (i = 0; i < slsiridb->len; i++)
uv_mutex_lock(&siridb->shards_mutex);
- slshards = imap_2slist_ref(siridb->shards);
+ slshards = imap_2vec_ref(siridb->shards);
uv_mutex_unlock(&siridb->shards_mutex);
siridb_shard_decref(shard);
}
- slist_free(slshards);
+ vec_free(slshards);
if (siri_optimize_wait() == SIRI_OPTIMIZE_CANCELLED)
{
OPTIMIZE_cleanup(slsiridb);
}
-static void OPTIMIZE_cleanup(slist_t * slsiridb)
+static void OPTIMIZE_cleanup(vec_t * slsiridb)
{
if (slsiridb != NULL)
{
siridb_decref(siridb);
}
- slist_free(slsiridb);
+ vec_free(slsiridb);
}
}
--- /dev/null
+/*
+ * account.c - SiriDB Service Account.
+ */
+#include <siri/service/account.h>
+#include <stddef.h>
+#include <owcrypt/owcrypt.h>
+#include <xpath/xpath.h>
+#include <siri/siri.h>
+#include <stdarg.h>
+#include <logger/logger.h>
+
+#define SIRI_SERVICE_ACCOUNT_SCHEMA 1
+#define FILENAME ".accounts.dat"
+
+#define DEFAULT_ACCOUNT "sa"
+#define DEFAULT_PASSWORD "siri"
+
+static int ACCOUNT_free(siri_service_account_t * account, void * args);
+static int ACCOUNT_save(siri_service_account_t * account, qp_fpacker_t * fpacker);
+static void ACCOUNT_msg(char * err_msg, char * fmt, ...);
+static int ACCOUNT_cmp(
+ siri_service_account_t * account,
+ qp_obj_t * qp_account);
+
+/*
+ * Initialize siri->accounts. Returns 0 if successful or -1 in case of an error
+ * (a signal might be raised because of qpack)
+ */
+int siri_service_account_init(siri_t * siri)
+{
+ qp_unpacker_t * unpacker;
+ qp_obj_t qp_schema;
+ qp_obj_t qp_account;
+ qp_obj_t qp_password;
+ int rc = 0;
+
+ /* get service accounts file name */
+ char fn[strlen(siri->cfg->default_db_path) + strlen(FILENAME) + 1];
+
+ /* initialize linked list */
+ siri->accounts = llist_new();
+ if (siri->accounts == NULL)
+ {
+ return -1;
+ }
+
+ /* make filename */
+ sprintf(fn, "%s%s", siri->cfg->default_db_path, FILENAME);
+
+ if (!xpath_file_exist(fn))
+ {
+ /* missing file, lets create the first account */
+ qp_account.via.raw = (unsigned char *) DEFAULT_ACCOUNT;
+ qp_account.len = 4;
+ qp_password.via.raw = (unsigned char *) DEFAULT_PASSWORD;
+ qp_password.len = 4;
+
+ return (siri_service_account_new(
+ siri,
+ &qp_account,
+ &qp_password,
+ 0,
+ NULL) || siri_service_account_save(siri, NULL));
+ }
+
+ if ((unpacker = qp_unpacker_ff(fn)) == NULL)
+ {
+ return -1; /* a signal is raised is case of a memory error */
+ }
+
+ if ( !qp_is_array(qp_next(unpacker, NULL)) ||
+ qp_next(unpacker, &qp_schema) != QP_INT64 ||
+ qp_schema.via.int64 != SIRI_SERVICE_ACCOUNT_SCHEMA)
+ {
+ log_critical("Invalid schema detected in '%s'", fn);
+ qp_unpacker_ff_free(unpacker);
+ return -1;
+ }
+
+ while ( rc == 0 &&
+ qp_is_array(qp_next(unpacker, NULL)) &&
+ qp_next(unpacker, &qp_account) == QP_RAW &&
+ qp_next(unpacker, &qp_password) == QP_RAW &&
+ qp_password.len > 12) /* old and new passwords are > 12 */
+ {
+ rc = siri_service_account_new(siri, &qp_account, &qp_password, 1, NULL);
+ }
+
+ qp_unpacker_ff_free(unpacker);
+ return rc;
+}
+
+/*
+ * Creates a new service account and returns 0 if successful. In case of
+ * an error, -1 is returned, err_msg is set.
+ *
+ * When successful, the account is added to the siri->accounts linked list.
+ *
+ * is_encrypted should be zero if the password is not encrypted yet.
+ *
+ * Note: the account will not be saved to disk. Call siri_service_account_save()
+ * to save a new service account.
+ */
+int siri_service_account_new(
+ siri_t * siri,
+ qp_obj_t * qp_account,
+ qp_obj_t * qp_password,
+ int is_encrypted,
+ char * err_msg)
+{
+ siri_service_account_t * account;
+
+ account = (siri_service_account_t *) llist_get(
+ siri->accounts,
+ (llist_cb) ACCOUNT_cmp,
+ (void *) qp_account);
+
+ if (account != NULL)
+ {
+ ACCOUNT_msg(
+ err_msg,
+ "service account '%.*s' already exists",
+ (int) qp_account->len,
+ qp_account->via.raw);
+ return -1;
+ }
+
+ if (qp_account->len < 2)
+ {
+ ACCOUNT_msg(
+ err_msg,
+ "service account name should have at least 2 characters");
+ return -1;
+ }
+
+ if (qp_password->len < 2)
+ {
+ ACCOUNT_msg(
+ err_msg,
+ "service account password should have at least 2 characters");
+ return -1;
+ }
+
+ account = (siri_service_account_t *) malloc(sizeof(siri_service_account_t));
+ if (account == NULL)
+ {
+ ACCOUNT_msg(err_msg, "memory allocation error");
+ return -1;
+ }
+
+ account->account = strndup(
+ (const char *) qp_account->via.raw, qp_account->len);
+ account->password = strndup(
+ (const char *) qp_password->via.raw, qp_password->len);
+
+ if (!is_encrypted && account->password != NULL)
+ {
+ char encrypted[OWCRYPT_SZ];
+ char salt[OWCRYPT_SALT_SZ];
+
+ /* generate a random salt */
+ owcrypt_gen_salt(salt);
+
+ /* encrypt the accounts password */
+ owcrypt(account->password, salt, encrypted);
+
+ /* replace with encrypted password */
+ free(account->password);
+ account->password = strdup(encrypted);
+ }
+
+ if ( account->account == NULL ||
+ account->password == NULL ||
+ llist_append(siri->accounts, account))
+ {
+ ACCOUNT_msg(err_msg, "memory allocation error");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Returns 0 if the account/password is valid or another value if not.
+ */
+int siri_service_account_check(
+ siri_t * siri,
+ qp_obj_t * qp_account,
+ qp_obj_t * qp_password,
+ char * err_msg)
+{
+ siri_service_account_t * account;
+ char pw[OWCRYPT_SZ];
+ char * password;
+
+ account = (siri_service_account_t *) llist_get(
+ siri->accounts,
+ (llist_cb) ACCOUNT_cmp,
+ (void *) qp_account);
+
+ if (account == NULL)
+ {
+ ACCOUNT_msg(
+ err_msg,
+ "cannot find service account '%.*s'",
+ (int) qp_account->len,
+ qp_account->via.raw);
+ return -1;
+ }
+
+ password= strndup(
+ (const char *) qp_password->via.raw, qp_password->len);
+
+ if (password == NULL)
+ {
+ ACCOUNT_msg(err_msg, "memory allocation error");
+ return -1;
+ }
+
+ owcrypt(password, account->password, pw);
+ free(password);
+
+ if (strcmp(pw, account->password))
+ {
+ ACCOUNT_msg(
+ err_msg,
+ "incorrect password for service account '%.*s'",
+ (int) qp_account->len,
+ qp_account->via.raw);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Returns 0 if the password is successful changed or -1 if not.
+ *
+ * Note: the password change is not saved, call siri_service_account_save().
+ */
+int siri_service_account_change_password(
+ siri_t * siri,
+ qp_obj_t * qp_account,
+ qp_obj_t * qp_password,
+ char * err_msg)
+{
+ siri_service_account_t * account;
+ char encrypted[OWCRYPT_SZ];
+ char salt[OWCRYPT_SALT_SZ];
+ char * password;
+
+ account = (siri_service_account_t *) llist_get(
+ siri->accounts,
+ (llist_cb) ACCOUNT_cmp,
+ (void *) qp_account);
+
+ if (account == NULL)
+ {
+ ACCOUNT_msg(
+ err_msg,
+ "cannot find service account '%.*s'",
+ (int) qp_account->len,
+ qp_account->via.raw);
+ return -1;
+ }
+
+ password= strndup(
+ (const char *) qp_password->via.raw, qp_password->len);
+
+ if (password == NULL)
+ {
+ ACCOUNT_msg(err_msg, "memory allocation error");
+ return -1;
+ }
+
+ /* generate a random salt */
+ owcrypt_gen_salt(salt);
+
+ /* encrypt the accounts password */
+ owcrypt(password, salt, encrypted);
+
+ free(password);
+
+ password = strdup(encrypted);
+ if (password == NULL)
+ {
+ ACCOUNT_msg(err_msg, "memory allocation error");
+ return -1;
+ }
+
+ /* replace account password with new encrypted password */
+ free(account->password);
+ account->password = password;
+
+ return 0;
+}
+
+/*
+ * Returns 0 if dropped or -1 in case the account was not found.
+ *
+ * Note: accounts are not saved, call siri_service_account_save().
+ */
+int siri_service_account_drop(
+ siri_t * siri,
+ qp_obj_t * qp_account,
+ char * err_msg)
+{
+ siri_service_account_t * account;
+ account = (siri_service_account_t *) llist_remove(
+ siri->accounts,
+ (llist_cb) ACCOUNT_cmp,
+ (void *) qp_account);
+ if (account == NULL)
+ {
+ ACCOUNT_msg(
+ err_msg,
+ "cannot find service account '%.*s'",
+ (int) qp_account->len,
+ qp_account->via.raw);
+ return -1;
+ }
+
+ ACCOUNT_free(account, NULL);
+ return 0;
+}
+
+/*
+ * Destroy service accounts. siri->accounts is allowed to be NULL.
+ */
+void siri_service_account_destroy(siri_t * siri)
+{
+ if (siri->accounts != NULL)
+ {
+ llist_free_cb(siri->accounts, (llist_cb) ACCOUNT_free, NULL);
+ }
+}
+
+/*
+ * Returns 0 if successful or EOF if not.
+ */
+int siri_service_account_save(siri_t * siri, char * err_msg)
+{
+ qp_fpacker_t * fpacker;
+
+ /* get service accounts file name */
+ char fn[strlen(siri->cfg->default_db_path) + strlen(FILENAME) + 1];
+
+ /* make filename */
+ sprintf(fn, "%s%s", siri->cfg->default_db_path, FILENAME);
+
+ if (
+ /* open a new account file */
+ (fpacker = qp_open(fn, "w")) == NULL ||
+
+ /* open a new array */
+ qp_fadd_type(fpacker, QP_ARRAY_OPEN) ||
+
+ /* write the current schema */
+ qp_fadd_int16(fpacker, SIRI_SERVICE_ACCOUNT_SCHEMA) ||
+
+ /* we can and should skip this if we have no accounts to save */
+ llist_walk(siri->accounts, (llist_cb) ACCOUNT_save, fpacker) ||
+
+ /* close file pointer */
+ qp_close(fpacker))
+ {
+ ACCOUNT_msg(err_msg, "error saving service accounts");
+ return EOF;
+ }
+ return 0;
+}
+
+/*
+ * Destroy an account.
+ */
+static int ACCOUNT_free(
+ siri_service_account_t * account,
+ void * args __attribute__((unused)))
+{
+ free(account->account);
+ free(account->password);
+ free(account);
+ return 0;
+}
+
+/*
+ * Returns 0 if successful and -1 in case an error occurred.
+ */
+static int ACCOUNT_save(siri_service_account_t * account, qp_fpacker_t * fpacker)
+{
+ int rc = 0;
+
+ rc += qp_fadd_type(fpacker, QP_ARRAY2);
+ rc += qp_fadd_string(fpacker, account->account);
+ rc += qp_fadd_string(fpacker, account->password);
+
+ return rc;
+}
+
+static void ACCOUNT_msg(char * err_msg, char * fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ if (err_msg != NULL)
+ {
+ vsnprintf(err_msg, SIRI_MAX_SIZE_ERR_MSG, fmt, args);
+ }
+ else
+ {
+ log_error(fmt, args);
+ }
+ va_end(args);
+}
+
+static int ACCOUNT_cmp(
+ siri_service_account_t * account,
+ qp_obj_t * qp_account)
+{
+ size_t len = strlen(account->account);
+ return (len == qp_account->len && strncmp(
+ account->account,
+ (const char *) qp_account->via.raw,
+ len) == 0);
+}
--- /dev/null
+/*
+ * client.c - Client for expanding a SiriDB database.
+ */
+#include <string.h>
+#include <stdarg.h>
+#include <lock/lock.h>
+#include <logger/logger.h>
+#include <siri/siri.h>
+#include <siri/version.h>
+#include <siri/service/client.h>
+#include <siri/service/request.h>
+#include <siri/net/stream.h>
+#include <siri/net/protocol.h>
+#include <siri/net/tcp.h>
+#include <siri/db/server.h>
+
+/* 15 seconds */
+#define CLIENT_REQUEST_TIMEOUT 15000
+#define CLIENT_FLAGS_TIMEOUT 1
+#define CLIENT_FLAGS_NO_ROLLBACK 2
+#define MAX_VERSION_LEN 256
+
+enum
+{
+ CLIENT_REQUEST_INIT,
+ CLIENT_REQUEST_STATUS,
+ CLIENT_REQUEST_POOLS,
+ CLIENT_REQUEST_FILE_USERS,
+ CLIENT_REQUEST_FILE_GROUPS,
+ CLIENT_REQUEST_FILE_SERVERS,
+ CLIENT_REQUEST_FILE_DATABASE,
+ CLIENT_REQUEST_REGISTER_SERVER
+};
+
+static void CLIENT_write_cb(uv_write_t * req, int status);
+static void CLIENT_on_connect(uv_connect_t * req, int status);
+static void CLIENT_on_data(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void CLIENT_request_timeout(uv_timer_t * handle);
+static void CLIENT_on_auth_success(siri_service_client_t * adm_client);
+static int CLIENT_resolve_dns(
+ siri_service_client_t * adm_client,
+ int ai_family,
+ char * err_msg);
+static void CLIENT_on_resolved(
+ uv_getaddrinfo_t * resolver,
+ int status,
+ struct addrinfo * res);
+static void CLIENT_err(
+ siri_service_client_t * adm_client,
+ const char * fmt,
+ ...);
+static void CLIENT_send_pkg(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg);
+static void CLIENT_on_error_msg(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg);
+static void CLIENT_on_register_server(siri_service_client_t * adm_client);
+static void CLIENT_on_file_database(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg);
+static void CLIENT_on_file_servers(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg);
+static void CLIENT_on_file_groups(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg);
+static void CLIENT_on_file_users(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg);
+static void CLIENT_on_request_pools(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg);
+static void CLIENT_on_request_status(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg);
+
+/*
+ * Initializes a request for a new pool or replica and returns 0 when
+ * successful. In case of an error, err_msg will be set and a value other than
+ * 0 is returned. (a signal can be raised.) When successful and only when
+ * successful, a response will be send to the provided client using the given
+ * pid.
+ */
+int siri_service_client_request(
+ uint16_t pid,
+ uint16_t port,
+ int pool,
+ uuid_t * uuid,
+ qp_obj_t * host,
+ qp_obj_t * username,
+ qp_obj_t * password,
+ qp_obj_t * dbname,
+ const char * dbpath,
+ sirinet_stream_t * client,
+ char * err_msg)
+{
+ siri_service_client_t * adm_client;
+ struct in_addr sa;
+ struct in6_addr sa6;
+
+ if (siri.client != NULL)
+ {
+ sprintf(err_msg, "manage socket already in use");
+ return -1;
+ }
+
+ siri.client = sirinet_stream_new(STREAM_TCP_MANAGE, &CLIENT_on_data);
+ if (siri.client == NULL)
+ {
+ sprintf(err_msg, "memory allocation error");
+ return -1;
+ }
+
+ uv_tcp_init(siri.loop, (uv_tcp_t *) siri.client->stream);
+
+ adm_client = (siri_service_client_t *) malloc(sizeof(siri_service_client_t));
+ if (adm_client == NULL)
+ {
+ sirinet_stream_decref(siri.client);
+ sprintf(err_msg, "memory allocation error");
+ return -1;
+ }
+ adm_client->pid = pid;
+ adm_client->port = port;
+ adm_client->host = strndup(
+ (const char *) host->via.raw, host->len);
+ adm_client->username = strndup(
+ (const char *) username->via.raw, username->len);
+ adm_client->password = strndup(
+ (const char *) password->via.raw, password->len);
+ adm_client->dbname = strndup(
+ (const char *) dbname->via.raw, dbname->len);
+ adm_client->dbpath = strdup(dbpath);
+ adm_client->client = client;
+ adm_client->request = CLIENT_REQUEST_INIT;
+ adm_client->flags = 0;
+ adm_client->pool = pool;
+ memcpy(&adm_client->uuid, uuid, 16);
+
+
+ siri.client->origin = (void *) adm_client;
+
+ sirinet_stream_incref(adm_client->client);
+
+ if (adm_client->host == NULL ||
+ adm_client->username == NULL ||
+ adm_client->password == NULL ||
+ adm_client->dbname == NULL ||
+ adm_client->dbpath == NULL)
+ {
+ sirinet_stream_decref(siri.client);
+ sprintf(err_msg, "memory allocation error");
+ return -1;
+ }
+
+ if (inet_pton(AF_INET, adm_client->host, &sa))
+ {
+ /* IPv4 */
+ struct sockaddr_in dest;
+
+ uv_connect_t * req = (uv_connect_t *) malloc(sizeof(uv_connect_t));
+ if (req == NULL)
+ {
+ sirinet_stream_decref(siri.client);
+ sprintf(err_msg, "memory allocation error");
+ return -1;
+ }
+ log_debug(
+ "Trying to connect to '%s:%u'...",
+ adm_client->host,
+ adm_client->port);
+
+ uv_ip4_addr(adm_client->host, adm_client->port, &dest);
+ uv_tcp_connect(
+ req,
+ (uv_tcp_t *) siri.client->stream,
+ (const struct sockaddr *) &dest,
+ CLIENT_on_connect);
+ }
+ else if (inet_pton(AF_INET6, adm_client->host, &sa6))
+ {
+ /* IPv6 */
+ struct sockaddr_in6 dest6;
+
+ uv_connect_t * req = (uv_connect_t *) malloc(sizeof(uv_connect_t));
+ if (req == NULL)
+ {
+ sirinet_stream_decref(siri.client);
+ sprintf(err_msg, "memory allocation error");
+ return -1;
+ }
+ log_debug(
+ "Trying to connect to '%s:%u'...",
+ adm_client->host,
+ adm_client->port);
+ uv_ip6_addr(adm_client->host, adm_client->port, &dest6);
+ uv_tcp_connect(
+ req,
+ (uv_tcp_t *) siri.client->stream,
+ (const struct sockaddr *) &dest6,
+ CLIENT_on_connect);
+ }
+ else
+ {
+ if (CLIENT_resolve_dns(
+ adm_client,
+ dns_req_family_map[siri.cfg->ip_support],
+ err_msg))
+ {
+ sirinet_stream_decref(siri.client);
+ return -1; /* err_msg is set */
+ }
+ }
+ uv_timer_init(siri.loop, &siri.timer);
+ return 0;
+}
+
+/*
+ * Destroy the client request. (will be called when the socket is destroyed)
+ */
+void siri_service_client_free(siri_service_client_t * adm_client)
+{
+ if (adm_client != NULL)
+ {
+ sirinet_stream_decref(adm_client->client);
+ free(adm_client->host);
+ free(adm_client->username);
+ free(adm_client->password);
+ free(adm_client->dbname);
+ free(adm_client->dbpath);
+ free(adm_client);
+ }
+}
+/*
+ * Try to get an ip address from dns.
+ *
+ * This function should return 0 when we can start an attempt for discovering
+ * dns. When the result is not zero, CLIENT_on_resolved will not be called and
+ * err_msg is set.
+ */
+static int CLIENT_resolve_dns(
+ siri_service_client_t * adm_client,
+ int ai_family,
+ char * err_msg)
+{
+ struct addrinfo hints;
+ hints.ai_family = ai_family;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_flags = AI_NUMERICSERV;
+
+ uv_getaddrinfo_t * resolver =
+ (uv_getaddrinfo_t *) malloc(sizeof(uv_getaddrinfo_t));
+
+ if (resolver == NULL)
+ {
+ sprintf(err_msg, "memory allocation error");
+ return -1;
+ }
+
+ int result;
+ resolver->data = adm_client;
+
+ char port[6]= {'\0'};
+ sprintf(port, "%u", adm_client->port);
+
+ result = uv_getaddrinfo(
+ siri.loop,
+ resolver,
+ (uv_getaddrinfo_cb) CLIENT_on_resolved,
+ adm_client->host,
+ port,
+ &hints);
+
+ if (result)
+ {
+ snprintf(
+ err_msg,
+ SIRI_MAX_SIZE_ERR_MSG,
+ "getaddrinfo call error %s",
+ uv_err_name(result));
+ free(resolver);
+ }
+
+ return result;
+}
+
+/*
+ * Callback used to check if resolving an ip address was successful.
+ */
+static void CLIENT_on_resolved(
+ uv_getaddrinfo_t * resolver,
+ int status,
+ struct addrinfo * res)
+{
+ siri_service_client_t * adm_client = (siri_service_client_t *) resolver->data;
+
+ if (status < 0)
+ {
+ CLIENT_err(
+ adm_client,
+ "cannot resolve ip address for '%s' (error: %s)",
+ adm_client->host,
+ uv_err_name(status));
+ }
+ else
+ {
+ uv_connect_t * req = (uv_connect_t *) malloc(sizeof(uv_connect_t));
+ if (req == NULL)
+ {
+ CLIENT_err(adm_client, "memory allocation error");
+ }
+ else
+ {
+ uv_tcp_connect(
+ req,
+ (uv_tcp_t *) siri.client->stream,
+ (const struct sockaddr *) res->ai_addr,
+ CLIENT_on_connect);
+ }
+ }
+
+ uv_freeaddrinfo(res);
+ free(resolver);
+}
+
+/*
+ * In case a client request fails, this function should be called to end
+ * the request. A package with the error message will be send to the client.
+ */
+static void CLIENT_err(
+ siri_service_client_t * adm_client,
+ const char * fmt,
+ ...)
+{
+ char err_msg[SIRI_MAX_SIZE_ERR_MSG];
+
+ va_list args;
+ va_start(args, fmt);
+ vsnprintf(err_msg, SIRI_MAX_SIZE_ERR_MSG, fmt, args);
+ va_end(args);
+
+ sirinet_pkg_t * package = sirinet_pkg_err(
+ adm_client->pid,
+ strlen(err_msg),
+ CPROTO_ERR_SERVICE,
+ err_msg);
+
+ if (package != NULL)
+ {
+ sirinet_pkg_send(adm_client->client, package);
+ }
+
+ log_error(err_msg);
+
+ if (~adm_client->flags & CLIENT_FLAGS_NO_ROLLBACK)
+ {
+ siri_service_request_rollback(adm_client->dbpath);
+ }
+
+ sirinet_stream_decref(siri.client);
+
+ uv_close((uv_handle_t *) &siri.timer, NULL);
+}
+
+/*
+ * Send a package to the 'other' SiriDB server. This function can be used for
+ * sending api requests for all database information required to create the
+ * database. Note that all packages are send with the same pid so packages
+ * should be send in sequence, not parallel.
+ *
+ * Note: pkg will be freed by calling this function.
+ */
+static void CLIENT_send_pkg(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg)
+{
+ uv_write_t * req = (uv_write_t *) malloc(sizeof(uv_write_t));
+ if (req == NULL)
+ {
+ free(pkg);
+ CLIENT_err(adm_client, "memory allocation error");
+ }
+ req->data = adm_client;
+
+ adm_client->pkg = pkg;
+
+ /* set the correct check bit */
+ pkg->checkbit = pkg->tp ^ 255;
+
+ uv_timer_start(
+ &siri.timer,
+ CLIENT_request_timeout,
+ CLIENT_REQUEST_TIMEOUT,
+ 0);
+
+ siri.timer.data = adm_client;
+
+ uv_buf_t wrbuf = uv_buf_init(
+ (char *) pkg,
+ sizeof(sirinet_pkg_t) + pkg->len);
+
+ uv_write(
+ req,
+ siri.client->stream,
+ &wrbuf,
+ 1,
+ CLIENT_write_cb);
+}
+
+/*
+ * Write call-back.
+ */
+static void CLIENT_write_cb(uv_write_t * req, int status)
+{
+ siri_service_client_t * adm_client = (siri_service_client_t *) req->data;
+
+ if (status)
+ {
+ uv_timer_stop(&siri.timer);
+ CLIENT_err(adm_client, "socket write error: %s", uv_strerror(status));
+ }
+
+ free(adm_client->pkg);
+ free(req);
+}
+
+/*
+ * Called when a connection to the 'other' siridb server is made.
+ * An authentication request will be send by user/password since this will be
+ * using the client connection. (a signal can be raised)
+ */
+static void CLIENT_on_connect(uv_connect_t * req, int status)
+{
+ sirinet_stream_t * client = req->handle->data;
+ siri_service_client_t * adm_client = client->origin;
+
+ if (status == 0)
+ {
+ log_debug(
+ "Connected to SiriDB server: '%s:%u', "
+ "sending authentication request",
+ adm_client->host, adm_client->port);
+
+ uv_read_start(
+ req->handle,
+ sirinet_stream_alloc_buffer,
+ sirinet_stream_on_data);
+
+ sirinet_pkg_t * pkg;
+ qp_packer_t * packer = sirinet_packer_new(512);
+
+ if (packer == NULL)
+ {
+ CLIENT_err(adm_client, "memory allocation error");
+ }
+ else
+ {
+ if (qp_add_type(packer, QP_ARRAY3) ||
+ qp_add_string(packer, adm_client->username) ||
+ qp_add_string(packer, adm_client->password) ||
+ qp_add_string(packer, adm_client->dbname))
+ {
+ qp_packer_free(packer);
+ }
+ else
+ {
+ pkg = sirinet_packer2pkg(packer, 0, CPROTO_REQ_AUTH);
+ CLIENT_send_pkg(adm_client, pkg);
+ }
+
+ }
+ }
+ else
+ {
+ CLIENT_err(
+ adm_client,
+ "connecting to server '%s:%u' failed with error: %s",
+ adm_client->host,
+ adm_client->port,
+ uv_strerror(status));
+ }
+ free(req);
+}
+
+/*
+ * on-data call-back function.
+ */
+static void CLIENT_on_data(sirinet_stream_t * client, sirinet_pkg_t * pkg)
+{
+ siri_service_client_t * adm_client = client->origin;
+ log_debug(
+ "Client response received (pid: %" PRIu16
+ ", len: %" PRIu32 ", tp: %s)",
+ pkg->pid,
+ pkg->len,
+ sirinet_cproto_server_str(pkg->tp));
+
+ if (adm_client->flags & CLIENT_FLAGS_TIMEOUT)
+ {
+ log_error("Client response received which was timed-out earlier");
+ }
+ else
+ {
+ uv_timer_stop(&siri.timer);
+
+ switch ((cproto_server_t) pkg->tp)
+ {
+ case CPROTO_RES_AUTH_SUCCESS:
+ CLIENT_on_auth_success(adm_client);
+ break;
+ case CPROTO_RES_QUERY:
+ switch (adm_client->request)
+ {
+ case CLIENT_REQUEST_STATUS:
+ CLIENT_on_request_status(adm_client, pkg);
+ break;
+ case CLIENT_REQUEST_POOLS:
+ CLIENT_on_request_pools(adm_client, pkg);
+ break;
+ default:
+ CLIENT_err(adm_client, "unexpected query response");
+ }
+ break;
+ case CPROTO_RES_FILE:
+ switch (adm_client->request)
+ {
+ case CLIENT_REQUEST_FILE_USERS:
+ CLIENT_on_file_users(adm_client, pkg);
+ break;
+ case CLIENT_REQUEST_FILE_GROUPS:
+ CLIENT_on_file_groups(adm_client, pkg);
+ break;
+ case CLIENT_REQUEST_FILE_SERVERS:
+ CLIENT_on_file_servers(adm_client, pkg);
+ break;
+ case CLIENT_REQUEST_FILE_DATABASE:
+ CLIENT_on_file_database(adm_client, pkg);
+ break;
+ default:
+ CLIENT_err(adm_client, "unexpected query response");
+ }
+ break;
+ case CPROTO_RES_ACK:
+ switch (adm_client->request)
+ {
+ case CLIENT_REQUEST_REGISTER_SERVER:
+ CLIENT_on_register_server(adm_client);
+ break;
+ default:
+ CLIENT_err(adm_client, "unexpected query response");
+ }
+ break;
+ case CPROTO_ERR_AUTH_CREDENTIALS:
+ CLIENT_err(
+ adm_client,
+ "invalid credentials for database '%s' on server '%s:%u'",
+ adm_client->dbname,
+ adm_client->host,
+ adm_client->port);
+ break;
+ case CPROTO_ERR_AUTH_UNKNOWN_DB:
+ CLIENT_err(
+ adm_client,
+ "database '%s' does not exist on server '%s:%u'",
+ adm_client->dbname,
+ adm_client->host,
+ adm_client->port);
+ break;
+ case CPROTO_ERR_MSG:
+ case CPROTO_ERR_QUERY:
+ case CPROTO_ERR_INSERT:
+ case CPROTO_ERR_SERVER:
+ case CPROTO_ERR_POOL:
+ case CPROTO_ERR_USER_ACCESS:
+ CLIENT_on_error_msg(adm_client, pkg);
+ break;
+ default:
+ CLIENT_err(
+ adm_client,
+ "unexpected response (%u) received from server '%s:%u'",
+ pkg->tp,
+ adm_client->host,
+ adm_client->port);
+ }
+ }
+}
+
+/*
+ * Called when register server was successful.
+ */
+static void CLIENT_on_register_server(siri_service_client_t * adm_client)
+{
+ sirinet_pkg_t * package = sirinet_pkg_new(
+ adm_client->pid,
+ 0,
+ CPROTO_ACK_SERVICE,
+ NULL);
+
+ if (package != NULL)
+ {
+ sirinet_pkg_send(adm_client->client, package);
+ }
+
+ log_info(
+ "Finished registering server on database '%s'",
+ adm_client->dbname);
+
+ sirinet_stream_decref(siri.client);
+ uv_close((uv_handle_t *) &siri.timer, NULL);
+}
+
+/*
+ * Called when database.dat is received.
+ */
+static void CLIENT_on_file_database(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg)
+{
+ FILE * fp;
+ qp_unpacker_t unpacker;
+ qp_obj_t qp_uuid;
+ siridb_t * siridb;
+ int rc;
+ /* 13 = strlen("database.dat")+1 */
+ char fn[strlen(adm_client->dbpath) + 13];
+ sprintf(fn, "%sdatabase.dat", adm_client->dbpath);
+
+ qp_unpacker_init(&unpacker, pkg->data, pkg->len);
+
+ if (qp_is_array(qp_next(&unpacker, NULL)) &&
+ /* schema check is not required at this moment but can be done here */
+ qp_next(&unpacker, NULL) == QP_INT64 &&
+ qp_next(&unpacker, &qp_uuid) == QP_RAW &&
+ qp_uuid.len == 16)
+ {
+ memcpy(unpacker.pt - 16, &adm_client->uuid, 16);
+ }
+ else
+ {
+ CLIENT_err(adm_client, "invalid database file received");
+ return;
+ }
+
+ fp = fopen(fn, "w");
+
+ if (fp == NULL)
+ {
+ CLIENT_err(adm_client, "cannot write or create file: %s", fn);
+ return;
+ }
+
+ rc = fwrite(pkg->data, pkg->len, 1, fp);
+
+ if (fclose(fp) || rc != 1)
+ {
+ CLIENT_err(adm_client, "cannot write or create file: %s", fn);
+ return;
+ }
+
+ siridb = siridb_new(adm_client->dbpath, LOCK_QUIT_IF_EXIST);
+
+ if (siridb == NULL)
+ {
+ CLIENT_err(adm_client, "error loading database");
+ return;
+ }
+
+ /* roll-back is not possible anymore */
+ adm_client->flags |= CLIENT_FLAGS_NO_ROLLBACK;
+
+ siridb->server->flags |= SERVER_FLAG_RUNNING;
+
+ /* Force one heart-beat */
+ siri_heartbeat_force();
+
+ sirinet_pkg_t * package;
+ qp_packer_t * packer = sirinet_packer_new(512);
+
+ if (packer == NULL)
+ {
+ CLIENT_err(adm_client, "memory allocation error");
+ return;
+ }
+
+ adm_client->request = CLIENT_REQUEST_REGISTER_SERVER;
+
+ if (qp_add_type(packer, QP_ARRAY4) ||
+ qp_add_raw(packer, (const unsigned char *) &adm_client->uuid, 16) ||
+ qp_add_string(packer, siri.cfg->server_address) ||
+ qp_add_int32(packer, (int32_t) siri.cfg->listen_backend_port) ||
+ qp_add_int32(packer, (int32_t) adm_client->pool))
+ {
+ qp_packer_free(packer);
+ CLIENT_err(adm_client, "memory allocation error");
+ return;
+ }
+
+ package = sirinet_packer2pkg(packer, 0, CPROTO_REQ_REGISTER_SERVER);
+ CLIENT_send_pkg(adm_client, package);
+}
+
+/*
+ * Called when servers.dat is received.
+ */
+static void CLIENT_on_file_servers(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg)
+{
+ FILE * fp;
+ qp_unpacker_t unpacker;
+ qp_types_t tp;
+ int rc, n, close_num;
+ /* 12 = strlen("servers.dat") + 1 */
+ char fn[strlen(adm_client->dbpath) + 12];
+ sprintf(fn, "%sservers.dat", adm_client->dbpath);
+
+ fp = fopen(fn, "w");
+ if (fp == NULL)
+ {
+ CLIENT_err(adm_client, "cannot write or create file: %s", fn);
+ return;
+ }
+
+ qp_unpacker_init(&unpacker, pkg->data, pkg->len);
+ tp = qp_next(&unpacker, NULL);
+ if (tp >= QP_ARRAY0 && tp <= QP_ARRAY5)
+ {
+ pkg->data[0] = QP_ARRAY_OPEN;
+ }
+ else if (tp != QP_ARRAY_OPEN)
+ {
+ CLIENT_err(adm_client, "invalid server status response");
+ return;
+ }
+
+ /* schema checking is not required at this moment but can be done here */
+ qp_next(&unpacker, NULL);
+
+ tp = qp_next(&unpacker, NULL);
+
+ if (!qp_is_array(tp))
+ {
+ CLIENT_err(adm_client, "invalid server status response");
+ return;
+ }
+
+ close_num = (tp == QP_ARRAY_OPEN) ? 1 : 0;
+
+ /* trim closing */
+ for (n = pkg->len;
+ (unsigned char) pkg->data[n - 1] == QP_ARRAY_CLOSE;
+ n--);
+
+ rc = (fwrite(pkg->data, n, 1, fp) == 1) ? 0 : EOF;
+
+ if (close_num)
+ {
+ rc += qp_fadd_type(fp, QP_ARRAY_CLOSE);
+ }
+
+ rc += qp_fadd_type(fp, QP_ARRAY4);
+ rc += qp_fadd_raw(fp, (const unsigned char *) &adm_client->uuid, 16);
+ rc += qp_fadd_string(fp, siri.cfg->server_address);
+ rc += qp_fadd_int32(fp, (int32_t) siri.cfg->listen_backend_port);
+ rc += qp_fadd_int32(fp, (int32_t) adm_client->pool);
+ rc += fclose(fp);
+
+ if (rc)
+ {
+ CLIENT_err(adm_client, "cannot write or create file: %s", fn);
+ }
+ else
+ {
+ sirinet_pkg_t * package;
+ adm_client->request = CLIENT_REQUEST_FILE_DATABASE;
+ package = sirinet_pkg_new(0, 0, CPROTO_REQ_FILE_DATABASE, NULL);
+ if (package == NULL)
+ {
+ CLIENT_err(adm_client, "memory allocation error");
+ }
+ else
+ {
+ CLIENT_send_pkg(adm_client, package);
+ }
+ }
+}
+
+/*
+ * Called when groups.dat is received.
+ */
+static void CLIENT_on_file_groups(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg)
+{
+ FILE * fp;
+ /* 11 = strlen("groups.dat") + 1 */
+ char fn[strlen(adm_client->dbpath) + 11];
+ sprintf(fn, "%sgroups.dat", adm_client->dbpath);
+
+ fp = fopen(fn, "w");
+ if (fp == NULL)
+ {
+ CLIENT_err(adm_client, "cannot write or create file: %s", fn);
+ }
+ else
+ {
+ int rc = fwrite(pkg->data, pkg->len, 1, fp);
+
+ if (fclose(fp) || rc != 1)
+ {
+ CLIENT_err(adm_client, "cannot write data to file: %s", fn);
+ }
+ else
+ {
+ adm_client->request = CLIENT_REQUEST_FILE_SERVERS;
+ sirinet_pkg_t * package =
+ sirinet_pkg_new(0, 0, CPROTO_REQ_FILE_SERVERS, NULL);
+ if (package == NULL)
+ {
+ CLIENT_err(adm_client, "memory allocation error");
+ }
+ else
+ {
+ CLIENT_send_pkg(adm_client, package);
+ }
+ }
+ }
+}
+
+/*
+ * Called when users.dat is received.
+ */
+static void CLIENT_on_file_users(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg)
+{
+ FILE * fp;
+ /* 10 = strlen("users.dat") + 1 */
+ char fn[strlen(adm_client->dbpath) + 10];
+ sprintf(fn, "%susers.dat", adm_client->dbpath);
+
+ fp = fopen(fn, "w");
+ if (fp == NULL)
+ {
+ CLIENT_err(adm_client, "cannot write or create file: %s", fn);
+ }
+ else
+ {
+ int rc = fwrite(pkg->data, pkg->len, 1, fp);
+
+ if (fclose(fp) || rc != 1)
+ {
+ CLIENT_err(adm_client, "cannot write data to file: %s", fn);
+ }
+ else
+ {
+ adm_client->request = CLIENT_REQUEST_FILE_GROUPS;
+ sirinet_pkg_t * package =
+ sirinet_pkg_new(0, 0, CPROTO_REQ_FILE_GROUPS, NULL);
+ if (package == NULL)
+ {
+ CLIENT_err(adm_client, "memory allocation error");
+ }
+ else
+ {
+ CLIENT_send_pkg(adm_client, package);
+ }
+ }
+ }
+}
+
+/*
+ * Called when 'list pools ...' response is received.
+ * This function will check which pool number will be assigned for a new pool
+ * or checks if a given pool for a new replica is valid.
+ */
+static void CLIENT_on_request_pools(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg)
+{
+ qp_unpacker_t unpacker;
+ qp_unpacker_init(&unpacker, pkg->data, pkg->len);
+ qp_obj_t qp_val;
+ qp_obj_t qp_pool;
+ qp_obj_t qp_servers;
+ int columns_found = 0;
+ int validate_pool = -1;
+
+ if (!qp_is_map(qp_next(&unpacker, NULL)))
+ {
+ CLIENT_err(adm_client, "invalid server status response");
+ return;
+ }
+
+ qp_next(&unpacker, &qp_val);
+
+ while (qp_val.tp == QP_RAW)
+ {
+ if ( strncmp(
+ (const char *) qp_val.via.raw,
+ "columns",
+ qp_val.len) == 0 &&
+ qp_is_array(qp_next(&unpacker, NULL)) &&
+ qp_next(&unpacker, &qp_val) == QP_RAW &&
+ strncmp(
+ (const char *) qp_val.via.raw, "pool", qp_val.len) == 0 &&
+ qp_next(&unpacker, &qp_val) == QP_RAW &&
+ strncmp(
+ (const char *) qp_val.via.raw, "servers", qp_val.len) == 0)
+ {
+ if (qp_next(&unpacker, &qp_val) == QP_ARRAY_CLOSE)
+ {
+ qp_next(&unpacker, &qp_val);
+ }
+ columns_found = 1;
+ continue;
+ }
+ if ( strncmp(
+ (const char *) qp_val.via.raw, "pools", qp_val.len) == 0 &&
+ qp_is_array(qp_next(&unpacker, NULL)))
+ {
+ qp_next(&unpacker, &qp_val);
+
+ while (qp_is_array(qp_val.tp))
+ {
+ if (qp_next(&unpacker, &qp_pool) == QP_INT64 &&
+ qp_next(&unpacker, &qp_servers) == QP_INT64)
+ {
+ if (adm_client->pool < 0)
+ {
+ /* looking for a new pool */
+ if (qp_pool.via.int64 > validate_pool)
+ {
+ validate_pool = qp_pool.via.int64;
+ }
+ }
+ else
+ {
+ if (qp_pool.via.int64 == adm_client->pool)
+ {
+ if (qp_servers.via.int64 > 1)
+ {
+ CLIENT_err(
+ adm_client,
+ "pool %d has already %" PRId64
+ " servers",
+ adm_client->pool,
+ qp_servers.via.int64);
+ return;
+ }
+ else
+ {
+ validate_pool = 0;
+ }
+ }
+ }
+ }
+ else
+ {
+ CLIENT_err(adm_client, "invalid server status response");
+ return;
+ }
+ if (qp_next(&unpacker, &qp_val) == QP_ARRAY_CLOSE)
+ {
+ qp_next(&unpacker, &qp_val);
+ }
+ }
+ if (qp_val.tp == QP_ARRAY_CLOSE)
+ {
+ qp_next(&unpacker, &qp_val);
+ }
+ continue;
+ }
+
+ CLIENT_err(adm_client, "invalid server status response");
+ return;
+ }
+
+ if (!columns_found)
+ {
+ CLIENT_err(adm_client, "invalid server status response");
+ }
+ else
+ {
+ sirinet_pkg_t * package;
+
+ if (adm_client->pool < 0)
+ {
+ if (validate_pool == -1)
+ {
+ CLIENT_err(adm_client, "invalid server status response");
+ return;
+ }
+ /* set new correct pool in case we request a new pool */
+ adm_client->pool = validate_pool + 1;
+ }
+ else if (validate_pool == -1)
+ {
+ CLIENT_err(
+ adm_client,
+ "pool %d does not exist",
+ adm_client->pool);
+ return;
+ }
+
+ adm_client->request = CLIENT_REQUEST_FILE_USERS;
+ package = sirinet_pkg_new(0, 0, CPROTO_REQ_FILE_USERS, NULL);
+ if (package == NULL)
+ {
+ CLIENT_err(adm_client, "memory allocation error");
+ }
+ else
+ {
+ CLIENT_send_pkg(adm_client, package);
+ }
+ }
+}
+
+/*
+ * Called when 'list servers ...' response is received.
+ * This function will check if each current server has status running.
+ * (this is a pre-check, the final register call does check for all servers
+ * to have the running status once more)
+ */
+static void CLIENT_on_request_status(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg)
+{
+ qp_unpacker_t unpacker;
+ qp_unpacker_init(&unpacker, pkg->data, pkg->len);
+ qp_obj_t qp_val;
+ qp_obj_t qp_name;
+ qp_obj_t qp_status;
+ qp_obj_t qp_version;
+ int columns_found = 0;
+ int servers_found = 0;
+ char version[MAX_VERSION_LEN];
+
+ if (!qp_is_map(qp_next(&unpacker, NULL)))
+ {
+ CLIENT_err(adm_client, "invalid server status response");
+ return;
+ }
+
+ qp_next(&unpacker, &qp_val);
+
+ while (qp_val.tp == QP_RAW)
+ {
+ if ( strncmp(
+ (const char *) qp_val.via.raw,
+ "columns",
+ qp_val.len) == 0 &&
+ qp_is_array(qp_next(&unpacker, NULL)) &&
+ qp_next(&unpacker, &qp_val) == QP_RAW &&
+ strncmp(
+ (const char *) qp_val.via.raw, "name", qp_val.len) == 0 &&
+ qp_next(&unpacker, &qp_val) == QP_RAW &&
+ strncmp(
+ (const char *) qp_val.via.raw,
+ "status",
+ qp_val.len) == 0 &&
+ qp_next(&unpacker, &qp_val) == QP_RAW &&
+ strncmp(
+ (const char *) qp_val.via.raw, "version", qp_val.len) == 0)
+ {
+ if (qp_next(&unpacker, &qp_val) == QP_ARRAY_CLOSE)
+ {
+ qp_next(&unpacker, &qp_val);
+ }
+ columns_found = 1;
+ continue;
+ }
+ if ( strncmp(
+ (const char *) qp_val.via.raw,
+ "servers",
+ qp_val.len) == 0 &&
+ qp_is_array(qp_next(&unpacker, NULL)))
+ {
+ qp_next(&unpacker, &qp_val);
+
+ while (qp_is_array(qp_val.tp))
+ {
+ if (qp_next(&unpacker, &qp_name) == QP_RAW &&
+ qp_next(&unpacker, &qp_status) == QP_RAW &&
+ qp_next(&unpacker, &qp_version) == QP_RAW &&
+ qp_version.len < MAX_VERSION_LEN)
+ {
+ /* copy and null terminate version */
+ memcpy(version, qp_version.via.raw, qp_version.len);
+ version[qp_version.len] = '\0';
+
+ if (siri_version_cmp(version, SIRIDB_VERSION))
+ {
+ CLIENT_err(
+ adm_client,
+ "server '%.*s' is running on version %s "
+ "while version %s is expected. (all SiriBD "
+ "servers should run the same version)",
+ (int) qp_name.len,
+ qp_name.via.raw,
+ version,
+ SIRIDB_VERSION);
+ return;
+ }
+
+ if (strncmp(
+ (const char *) qp_status.via.raw,
+ "running",
+ qp_status.len) != 0)
+ {
+ CLIENT_err(
+ adm_client,
+ "server '%.*s' has status: '%.*s'",
+ (int) qp_name.len,
+ qp_name.via.raw,
+ (int) qp_status.len,
+ qp_status.via.raw);
+ return;
+ }
+ servers_found++;
+ }
+ else
+ {
+ CLIENT_err(adm_client, "invalid server status response");
+ return;
+ }
+ if (qp_next(&unpacker, &qp_val) == QP_ARRAY_CLOSE)
+ {
+ qp_next(&unpacker, &qp_val);
+ }
+ }
+ if (qp_val.tp == QP_ARRAY_CLOSE)
+ {
+ qp_next(&unpacker, &qp_val);
+ }
+ continue;
+ }
+
+ CLIENT_err(adm_client, "invalid server status response");
+ return;
+ }
+
+ if (!servers_found || !columns_found)
+ {
+ CLIENT_err(adm_client, "invalid server status response");
+ }
+ else
+ {
+ sirinet_pkg_t * package;
+ qp_packer_t * packer = sirinet_packer_new(512);
+ if (packer == NULL)
+ {
+ CLIENT_err(adm_client, "memory allocation error");
+ }
+ else
+ {
+ adm_client->request = CLIENT_REQUEST_POOLS;
+
+ /* no need to check since this will always fit */
+ qp_add_type(packer, QP_ARRAY1);
+ qp_add_string(packer, "list pools pool, servers");
+ package = sirinet_packer2pkg(packer, 0, CPROTO_REQ_QUERY);
+ CLIENT_send_pkg(adm_client, package);
+ }
+ }
+}
+
+/*
+ * Called when an error message is received.
+ */
+static void CLIENT_on_error_msg(
+ siri_service_client_t * adm_client,
+ sirinet_pkg_t * pkg)
+{
+ qp_unpacker_t unpacker;
+ qp_unpacker_init(&unpacker, pkg->data, pkg->len);
+ qp_obj_t qp_err;
+
+ if (qp_is_map(qp_next(&unpacker, NULL)) &&
+ qp_next(&unpacker, NULL) == QP_RAW &&
+ qp_next(&unpacker, &qp_err) == QP_RAW)
+ {
+ CLIENT_err(
+ adm_client,
+ "error on server '%s:%u': %.*s",
+ adm_client->host,
+ adm_client->port,
+ (int) qp_err.len,
+ qp_err.via.raw);
+ }
+ else
+ {
+ CLIENT_err(
+ adm_client,
+ "unexpected error on server '%s:%u'",
+ adm_client->host,
+ adm_client->port);
+ }
+}
+
+/*
+ * Called when authentication is successful.
+ */
+static void CLIENT_on_auth_success(siri_service_client_t * adm_client)
+{
+ sirinet_pkg_t * pkg;
+ qp_packer_t * packer = sirinet_packer_new(512);
+ if (packer == NULL)
+ {
+ CLIENT_err(adm_client, "memory allocation error");
+ }
+ else
+ {
+ adm_client->request = CLIENT_REQUEST_STATUS;
+
+ /* no need to check since this will always fit */
+ qp_add_type(packer, QP_ARRAY1);
+ qp_add_string(packer, "list servers name, status, version");
+ pkg = sirinet_packer2pkg(packer, 0, CPROTO_REQ_QUERY);
+ CLIENT_send_pkg(adm_client, pkg);
+ }
+}
+
+/*
+ * Timeout on a client request.
+ */
+static void CLIENT_request_timeout(uv_timer_t * handle)
+{
+ siri_service_client_t * adm_client = (siri_service_client_t *) handle->data;
+
+ adm_client->flags |= CLIENT_FLAGS_TIMEOUT;
+
+ CLIENT_err(adm_client, "request timeout");
+}
--- /dev/null
+/*
+ * request.c - SiriDB Service Request.
+ */
+#define PCRE2_CODE_UNIT_WIDTH 8
+
+#include <siri/service/account.h>
+#include <siri/service/client.h>
+#include <stddef.h>
+#include <siri/service/request.h>
+#include <siri/siri.h>
+#include <logger/logger.h>
+#include <pcre2.h>
+#include <lock/lock.h>
+#include <xmath/xmath.h>
+#include <unistd.h>
+#include <uuid/uuid.h>
+#include <siri/db/server.h>
+#include <siri/db/buffer.h>
+#include <siri/version.h>
+#include <siri/db/reindex.h>
+
+#define DEFAULT_TIME_PRECISION 1
+#define DEFAULT_BUFFER_SIZE 1024
+#define DEFAULT_DURATION_NUM 604800
+#define DEFAULT_DURATION_LOG 86400
+#define DB_CONF_FN "database.conf"
+#define DB_DAT_FN "database.dat"
+#define DEFAULT_CONF \
+"#\n" \
+"# Welcome to the SiriDB configuration file\n" \
+"#\n" \
+"\n" \
+"[buffer]\n" \
+"# Alternative path to save the buffer file.\n" \
+"# In case you later plan to change this location you manually need to move\n" \
+"# the buffer file to the new location.\n" \
+"# path = <buffer_path>\n" \
+"\n" \
+"# Buffer size in bytes. This size must be a multiple of 512 with a maximum\n" \
+"# of 1048576 bytes. Be careful using large values since SiriDB will require\n" \
+"# memory based on this value. A value between 1024 and 32768 is recommended.\n" \
+"# size = 1024\n"
+
+#define CHECK_DBNAME_AND_CREATE_PATH \
+ pcre_exec_ret = pcre2_match( \
+ siri.dbname_regex, \
+ (PCRE2_SPTR8) qp_dbname.via.raw, \
+ qp_dbname.len, \
+ 0, \
+ 0, \
+ siri.dbname_match_data, \
+ NULL); \
+ \
+ if (pcre_exec_ret < 0) \
+ { \
+ snprintf( \
+ err_msg, \
+ SIRI_MAX_SIZE_ERR_MSG, \
+ "invalid database name: '%.*s'", \
+ (int) qp_dbname.len, \
+ qp_dbname.via.raw); \
+ return CPROTO_ERR_SERVICE; \
+ } \
+ \
+ if (llist_get( \
+ siri.siridb_list, \
+ (llist_cb) SERVICE_find_database, \
+ &qp_dbname) != NULL) \
+ { \
+ snprintf( \
+ err_msg, \
+ SIRI_MAX_SIZE_ERR_MSG, \
+ "database name already exists: '%.*s'", \
+ (int) qp_dbname.len, \
+ qp_dbname.via.raw); \
+ return CPROTO_ERR_SERVICE; \
+ } \
+ \
+ dbpath_len = strlen(siri.cfg->default_db_path) + qp_dbname.len + 2; \
+ char dbpath[dbpath_len]; \
+ sprintf(dbpath, \
+ "%s%.*s/", \
+ siri.cfg->default_db_path, \
+ (int) qp_dbname.len, \
+ qp_dbname.via.raw); \
+ \
+ if (stat(dbpath, &st) != -1) \
+ { \
+ snprintf( \
+ err_msg, \
+ SIRI_MAX_SIZE_ERR_MSG, \
+ "database directory already exists: %s", \
+ dbpath); \
+ return CPROTO_ERR_SERVICE; \
+ } \
+ \
+ if (mkdir(dbpath, 0700) == -1) \
+ { \
+ snprintf( \
+ err_msg, \
+ SIRI_MAX_SIZE_ERR_MSG, \
+ "cannot create directory: %s", \
+ dbpath); \
+ return CPROTO_ERR_SERVICE; \
+ } \
+ \
+ char dbfn[dbpath_len + max_filename_sz]; \
+ sprintf(dbfn, "%s%s", dbpath, DB_CONF_FN); \
+ \
+ fp = fopen(dbfn, "w"); \
+ if (fp == NULL) \
+ { \
+ siri_service_request_rollback(dbpath); \
+ snprintf( \
+ err_msg, \
+ SIRI_MAX_SIZE_ERR_MSG, \
+ "cannot open file for writing: %s", \
+ dbfn); \
+ return CPROTO_ERR_SERVICE; \
+ } \
+ \
+ rc = fputs(DEFAULT_CONF, fp); \
+ \
+ if (fclose(fp) || rc < 0) \
+ { \
+ siri_service_request_rollback(dbpath); \
+ snprintf( \
+ err_msg, \
+ SIRI_MAX_SIZE_ERR_MSG, \
+ "cannot write file: %s", \
+ dbfn); \
+ return CPROTO_ERR_SERVICE; \
+ }
+
+static cproto_server_t SERVICE_on_new_account(
+ qp_unpacker_t * qp_unpacker,
+ char * err_msg);
+static cproto_server_t SERVICE_on_change_password(
+ qp_unpacker_t * qp_unpacker,
+ char * err_msg);
+static cproto_server_t SERVICE_on_drop_account(
+ qp_unpacker_t * qp_unpacker,
+ qp_obj_t * qp_account,
+ char * err_msg);
+static cproto_server_t SERVICE_on_new_database(
+ qp_unpacker_t * qp_unpacker,
+ char * err_msg);
+static cproto_server_t SERVICE_on_new_replica_or_pool(
+ qp_unpacker_t * qp_unpacker,
+ uint16_t pid,
+ sirinet_stream_t * client,
+ int req,
+ char * err_msg);
+static cproto_server_t SERVICE_on_get_version(
+ qp_unpacker_t * qp_unpacker,
+ qp_packer_t ** packaddr,
+ char * err_msg);
+static cproto_server_t SERVICE_on_get_accounts(
+ qp_unpacker_t * qp_unpacker,
+ qp_packer_t ** packaddr,
+ char * err_msg);
+static cproto_server_t SERVICE_on_get_databases(
+ qp_unpacker_t * qp_unpacker,
+ qp_packer_t ** packaddr,
+ char * err_msg);
+static int8_t SERVICE_time_precision(qp_obj_t * qp_time_precision);
+static int64_t SERVICE_duration(qp_obj_t * qp_duration, uint8_t time_precision);
+static int SERVICE_list_databases(siridb_t * siridb, qp_packer_t * packer);
+static int SERVICE_find_database(siridb_t * siridb, qp_obj_t * dbname);
+static int SERVICE_list_accounts(
+ siri_service_account_t * account,
+ qp_packer_t * packer);
+
+static size_t max_filename_sz;
+
+/*
+ * Initialize service requests. (called once when initializing SiriDB)
+ */
+int siri_service_request_init(void)
+{
+ max_filename_sz = xmath_max_size(
+ 3,
+ strlen(DB_CONF_FN),
+ strlen(DB_DAT_FN),
+ strlen(REINDEX_FN));
+
+ int pcre_error_num;
+ PCRE2_SIZE pcre_error_offset;
+
+ pcre2_code * regex;
+ pcre2_match_data * match_data;
+
+ regex = pcre2_compile(
+ (PCRE2_SPTR8) "^[a-zA-Z][a-zA-Z0-9-_]{0,18}[a-zA-Z0-9]$",
+ PCRE2_ZERO_TERMINATED,
+ 0,
+ &pcre_error_num,
+ &pcre_error_offset,
+ NULL);
+ if (regex == NULL)
+ {
+ return -1;
+ }
+ match_data = pcre2_match_data_create_from_pattern(regex, NULL);
+
+ if(match_data == NULL)
+ {
+ pcre2_match_data_free(match_data);
+ pcre2_code_free(regex);
+ return -1;
+ }
+
+ siri.dbname_regex = regex;
+ siri.dbname_match_data = match_data;
+
+ return 0;
+}
+
+/*
+ * Destroy service requests. (only called when exiting SiriDB)
+ */
+void siri_service_request_destroy(void)
+{
+ pcre2_match_data_free(siri.dbname_match_data);
+ pcre2_code_free(siri.dbname_regex);
+}
+
+/*
+ * Returns CPROTO_ACK_SERVICE or CPROTO_DEFERRED when successful.
+ * In case of an error CPROTO_ERR_SERVICE can be returned in which case err_msg
+ * is set, or CPROTO_ERR_SERVICE_INVALID_REQUEST is returned.
+ */
+cproto_server_t siri_service_request(
+ int tp,
+ qp_unpacker_t * qp_unpacker,
+ qp_obj_t * qp_account,
+ qp_packer_t ** packaddr,
+ uint16_t pid,
+ sirinet_stream_t * client,
+ char * err_msg)
+{
+ switch ((service_request_t) tp)
+ {
+ case SERVICE_NEW_ACCOUNT_:
+ return SERVICE_on_new_account(qp_unpacker, err_msg);
+ case SERVICE_CHANGE_PASSWORD_:
+ return SERVICE_on_change_password(qp_unpacker, err_msg);
+ case SERVICE_DROP_ACCOUNT_:
+ return SERVICE_on_drop_account(qp_unpacker, qp_account, err_msg);
+ case SERVICE_NEW_DATABASE_:
+ return SERVICE_on_new_database(qp_unpacker, err_msg);
+ case SERVICE_NEW_POOL:
+ return SERVICE_on_new_replica_or_pool(
+ qp_unpacker,
+ pid,
+ client,
+ SERVICE_NEW_POOL,
+ err_msg);
+ case SERVICE_NEW_REPLICA:
+ return SERVICE_on_new_replica_or_pool(
+ qp_unpacker,
+ pid,
+ client,
+ SERVICE_NEW_REPLICA,
+ err_msg);
+ case SERVICE_GET_VERSION:
+ return SERVICE_on_get_version(qp_unpacker, packaddr, err_msg);
+ case SERVICE_GET_ACCOUNTS:
+ return SERVICE_on_get_accounts(qp_unpacker, packaddr, err_msg);
+ case SERVICE_GET_DATABASES:
+ return SERVICE_on_get_databases(qp_unpacker, packaddr, err_msg);
+ default:
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+}
+
+/*
+ * Returns CPROTO_ACK_SERVICE when successful.
+ * In case of an error CPROTO_ERR_SERVICE can be returned in which case err_msg
+ * is set, or CPROTO_ERR_SERVICE_INVALID_REQUEST is returned.
+ */
+static cproto_server_t SERVICE_on_new_account(
+ qp_unpacker_t * qp_unpacker,
+ char * err_msg)
+{
+ qp_obj_t qp_key, qp_account, qp_password;
+
+ qp_account.tp = QP_HOOK;
+ qp_password.tp = QP_HOOK;
+
+ if (!qp_is_map(qp_next(qp_unpacker, NULL)))
+ {
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ while (qp_next(qp_unpacker, &qp_key) == QP_RAW)
+ {
+ if ( strncmp(
+ (const char *) qp_key.via.raw,
+ "account",
+ qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_account) == QP_RAW)
+ {
+ continue;
+ }
+ if ( strncmp(
+ (const char *) qp_key.via.raw,
+ "password",
+ qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_password) == QP_RAW)
+ {
+ continue;
+ }
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ if (qp_account.tp == QP_HOOK || qp_password.tp == QP_HOOK)
+ {
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ return (siri_service_account_new(
+ &siri,
+ &qp_account,
+ &qp_password,
+ 0,
+ err_msg) ||
+ siri_service_account_save(&siri, err_msg)) ?
+ CPROTO_ERR_SERVICE : CPROTO_ACK_SERVICE;
+}
+
+/*
+ * Returns CPROTO_ACK_SERVICE when successful.
+ * In case of an error CPROTO_ERR_SERVICE can be returned in which case err_msg
+ * is set, or CPROTO_ERR_SERVICE_INVALID_REQUEST is returned.
+ */
+static cproto_server_t SERVICE_on_change_password(
+ qp_unpacker_t * qp_unpacker,
+ char * err_msg)
+{
+ qp_obj_t qp_key, qp_account, qp_password;
+
+ qp_account.tp = QP_HOOK;
+ qp_password.tp = QP_HOOK;
+
+ if (!qp_is_map(qp_next(qp_unpacker, NULL)))
+ {
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ while (qp_next(qp_unpacker, &qp_key) == QP_RAW)
+ {
+ if ( strncmp(
+ (const char *) qp_key.via.raw,
+ "account",
+ qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_account) == QP_RAW)
+ {
+ continue;
+ }
+ if ( strncmp(
+ (const char *) qp_key.via.raw,
+ "password",
+ qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_password) == QP_RAW)
+ {
+ continue;
+ }
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ if (qp_account.tp == QP_HOOK || qp_password.tp == QP_HOOK)
+ {
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ return (siri_service_account_change_password(
+ &siri,
+ &qp_account,
+ &qp_password,
+ err_msg) ||
+ siri_service_account_save(&siri, err_msg)) ?
+ CPROTO_ERR_SERVICE : CPROTO_ACK_SERVICE;
+}
+
+/*
+ * Returns CPROTO_ACK_SERVICE when successful.
+ * In case of an error CPROTO_ERR_SERVICE can be returned in which case err_msg
+ * is set, or CPROTO_ERR_SERVICE_INVALID_REQUEST is returned.
+ */
+static cproto_server_t SERVICE_on_drop_account(
+ qp_unpacker_t * qp_unpacker,
+ qp_obj_t * qp_account,
+ char * err_msg)
+{
+ qp_obj_t qp_key, qp_target;
+
+ qp_target.tp = QP_HOOK;
+
+ if (!qp_is_map(qp_next(qp_unpacker, NULL)))
+ {
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ while (qp_next(qp_unpacker, &qp_key) == QP_RAW)
+ {
+ if ( strncmp(
+ (const char *) qp_key.via.raw,
+ "account",
+ qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_target) == QP_RAW)
+ {
+ continue;
+ }
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ if (qp_target.tp == QP_HOOK)
+ {
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ if (qp_target.len == qp_account->len &&
+ strncmp(
+ (const char *) qp_target.via.raw,
+ (const char *) qp_account->via.raw,
+ qp_target.len) == 0)
+ {
+ sprintf(err_msg, "cannot drop your own account");
+ return CPROTO_ERR_SERVICE;
+ }
+
+ return (siri_service_account_drop(
+ &siri,
+ &qp_target,
+ err_msg) ||
+ siri_service_account_save(&siri, err_msg)) ?
+ CPROTO_ERR_SERVICE : CPROTO_ACK_SERVICE;
+}
+
+/*
+ * Returns CPROTO_ACK_SERVICE when successful.
+ * In case of an error CPROTO_ERR_SERVICE can be returned in which case err_msg
+ * is set, or CPROTO_ERR_SERVICE_INVALID_REQUEST is returned.
+ */
+static cproto_server_t SERVICE_on_new_database(
+ qp_unpacker_t * qp_unpacker,
+ char * err_msg)
+{
+ FILE * fp;
+ qp_obj_t
+ qp_key,
+ qp_dbname,
+ qp_time_precision,
+ qp_buffer_size,
+ qp_duration_num,
+ qp_duration_log;
+ size_t dbpath_len;
+ int pcre_exec_ret;
+ int rc;
+ struct stat st;
+ int8_t time_precision;
+ int64_t buffer_size, duration_num, duration_log;
+ siridb_t * siridb;
+ uuid_t uuid;
+
+ memset(&st, 0, sizeof(struct stat));
+
+ if (siri.siridb_list->len == MAX_NUMBER_DB)
+ {
+ sprintf(err_msg,
+ "maximum number of databases is reached (%zd)",
+ siri.siridb_list->len);
+ return CPROTO_ERR_SERVICE;
+ }
+
+ qp_dbname.tp = QP_HOOK;
+ qp_time_precision.tp = QP_HOOK;
+ qp_buffer_size.tp = QP_HOOK;
+ qp_duration_num.tp = QP_HOOK;
+ qp_duration_log.tp = QP_HOOK;
+
+ if (!qp_is_map(qp_next(qp_unpacker, NULL)))
+ {
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ while (qp_next(qp_unpacker, &qp_key) == QP_RAW)
+ {
+ if ( strncmp(
+ (const char *) qp_key.via.raw,
+ "dbname",
+ qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_dbname) == QP_RAW)
+ {
+ continue;
+ }
+ if ( strncmp(
+ (const char *) qp_key.via.raw,
+ "time_precision",
+ qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_time_precision) == QP_RAW)
+ {
+ continue;
+ }
+ if ( strncmp(
+ (const char *) qp_key.via.raw,
+ "buffer_size",
+ qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_buffer_size) == QP_INT64)
+ {
+ continue;
+ }
+ if ( strncmp(
+ (const char *) qp_key.via.raw,
+ "duration_num",
+ qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_duration_num) == QP_RAW)
+ {
+ continue;
+ }
+ if ( strncmp(
+ (const char *) qp_key.via.raw,
+ "duration_log",
+ qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_duration_log) == QP_RAW)
+ {
+ continue;
+ }
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ if (qp_dbname.tp == QP_HOOK)
+ {
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ time_precision = (qp_time_precision.tp == QP_HOOK) ?
+ DEFAULT_TIME_PRECISION : SERVICE_time_precision(&qp_time_precision);
+ if (time_precision == -1)
+ {
+ snprintf(
+ err_msg,
+ SIRI_MAX_SIZE_ERR_MSG,
+ "invalid time precision: '%.*s' (expecting s, ms, us or ns)",
+ (int) qp_time_precision.len,
+ qp_time_precision.via.raw);
+ return CPROTO_ERR_SERVICE;
+ }
+
+ duration_num = (qp_duration_num.tp == QP_HOOK) ?
+ DEFAULT_DURATION_NUM * xmath_ipow(1000, time_precision):
+ SERVICE_duration(&qp_duration_num, time_precision);
+
+ if (duration_num == -1)
+ {
+ snprintf(
+ err_msg,
+ SIRI_MAX_SIZE_ERR_MSG,
+ "invalid number duration: '%.*s' "
+ "(valid examples: 6h, 2d or 1w)",
+ (int) qp_duration_num.len,
+ qp_duration_num.via.raw);
+ return CPROTO_ERR_SERVICE;
+ }
+
+ duration_log = (qp_duration_log.tp == QP_HOOK) ?
+ DEFAULT_DURATION_LOG * xmath_ipow(1000, time_precision):
+ SERVICE_duration(&qp_duration_log, time_precision);
+
+ if (duration_log == -1)
+ {
+ snprintf(
+ err_msg,
+ SIRI_MAX_SIZE_ERR_MSG,
+ "invalid log duration: '%.*s' "
+ "(valid examples: 6h, 2d or 1w)",
+ (int) qp_duration_log.len,
+ qp_duration_log.via.raw);
+ return CPROTO_ERR_SERVICE;
+ }
+
+ buffer_size = (qp_buffer_size.tp == QP_HOOK) ?
+ DEFAULT_BUFFER_SIZE : qp_buffer_size.via.int64;
+
+ if (!siridb_buffer_is_valid_size(buffer_size))
+ {
+ sprintf(err_msg,
+ "invalid buffer size: %" PRId64
+ " (expecting a multiple of 512 with a maximum of %" PRId64 ")",
+ buffer_size,
+ (int64_t) MAX_BUFFER_SZ);
+ return CPROTO_ERR_SERVICE;
+ }
+
+ CHECK_DBNAME_AND_CREATE_PATH
+
+ sprintf(dbfn, "%s%s", dbpath, DB_DAT_FN);
+ fp = qp_open(dbfn, "w");
+ if (fp == NULL)
+ {
+ siri_service_request_rollback(dbpath);
+ snprintf(
+ err_msg,
+ SIRI_MAX_SIZE_ERR_MSG,
+ "cannot open file for writing: %s",
+ dbfn);
+ return CPROTO_ERR_SERVICE;
+ }
+ rc = 0;
+ uuid_generate(uuid);
+
+ if (qp_fadd_type(fp, QP_ARRAY_OPEN) ||
+ qp_fadd_int8(fp, SIRIDB_SCHEMA) ||
+ qp_fadd_raw(fp, (const unsigned char *) uuid, 16) ||
+ qp_fadd_raw(fp, qp_dbname.via.raw, qp_dbname.len) ||
+ qp_fadd_int8(fp, time_precision) ||
+ qp_fadd_int64(fp, buffer_size) ||
+ qp_fadd_int64(fp, duration_num) ||
+ qp_fadd_int64(fp, duration_log) ||
+ qp_fadd_string(fp, "NAIVE") ||
+ qp_fadd_double(fp, DEF_DROP_THRESHOLD) ||
+ qp_fadd_int64(fp, DEF_SELECT_POINTS_LIMIT) ||
+ qp_fadd_int64(fp, DEF_LIST_LIMIT) ||
+ qp_fadd_type(fp, QP_ARRAY_CLOSE))
+ {
+ rc = -1;
+ }
+
+ if (qp_close(fp) || rc == -1)
+ {
+ siri_service_request_rollback(dbpath);
+ snprintf(
+ err_msg,
+ SIRI_MAX_SIZE_ERR_MSG,
+ "cannot write file: %s",
+ dbfn);
+ return CPROTO_ERR_SERVICE;
+ }
+
+ siridb = siridb_new(dbpath, LOCK_QUIT_IF_EXIST);
+ if (siridb == NULL)
+ {
+ siri_service_request_rollback(dbpath);
+ sprintf(err_msg, "error loading database");
+ return CPROTO_ERR_SERVICE;
+ }
+
+ siridb->server->flags |= SERVER_FLAG_RUNNING;
+
+ /* Force one heart-beat */
+ siri_heartbeat_force();
+
+ return CPROTO_ACK_SERVICE;
+}
+
+/*
+ * Returns CPROTO_DEFERRED when successful.
+ * In case of an error CPROTO_ERR_SERVICE can be returned in which case err_msg
+ * is set, or CPROTO_ERR_SERVICE_INVALID_REQUEST is returned.
+ */
+static cproto_server_t SERVICE_on_new_replica_or_pool(
+ qp_unpacker_t * qp_unpacker,
+ uint16_t pid,
+ sirinet_stream_t * client,
+ int req,
+ char * err_msg)
+{
+ FILE * fp;
+ qp_obj_t
+ qp_key,
+ qp_dbname,
+ qp_pool,
+ qp_host,
+ qp_port,
+ qp_username,
+ qp_password;
+ size_t dbpath_len;
+ int pcre_exec_ret;
+ int rc;
+ struct stat st;
+ uint16_t port;
+ uuid_t uuid;
+
+ memset(&st, 0, sizeof(struct stat));
+
+ if (siri.siridb_list->len == MAX_NUMBER_DB)
+ {
+ sprintf(err_msg,
+ "maximum number of databases is reached (%zd)",
+ siri.siridb_list->len);
+ return CPROTO_ERR_SERVICE;
+ }
+
+ qp_dbname.tp = QP_HOOK;
+ qp_pool.tp = QP_HOOK;
+ qp_host.tp = QP_HOOK;
+ qp_port.tp = QP_HOOK;
+ qp_username.tp = QP_HOOK;
+ qp_password.tp = QP_HOOK;
+
+ if (!qp_is_map(qp_next(qp_unpacker, NULL)))
+ {
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ while (qp_next(qp_unpacker, &qp_key) == QP_RAW)
+ {
+ if ( strncmp(
+ (const char *) qp_key.via.raw,
+ "dbname",
+ qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_dbname) == QP_RAW)
+ {
+ continue;
+ }
+ if ( strncmp(
+ (const char *) qp_key.via.raw, "pool", qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_pool) == QP_INT64)
+ {
+ continue;
+ }
+ if ( strncmp(
+ (const char *) qp_key.via.raw, "host", qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_host) == QP_RAW)
+ {
+ continue;
+ }
+ if ( strncmp(
+ (const char *) qp_key.via.raw, "port", qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_port) == QP_INT64)
+ {
+ continue;
+ }
+ if ( strncmp(
+ (const char *) qp_key.via.raw,
+ "username",
+ qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_username) == QP_RAW)
+ {
+ continue;
+ }
+ if ( strncmp(
+ (const char *) qp_key.via.raw,
+ "password",
+ qp_key.len) == 0 &&
+ qp_next(qp_unpacker, &qp_password) == QP_RAW)
+ {
+ continue;
+ }
+
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ if (qp_dbname.tp == QP_HOOK ||
+ (
+ (req == SERVICE_NEW_POOL && qp_pool.tp != QP_HOOK) ||
+ (req == SERVICE_NEW_REPLICA && qp_pool.tp == QP_HOOK)
+ ) ||
+ qp_host.tp == QP_HOOK ||
+ qp_port.tp == QP_HOOK ||
+ qp_username.tp == QP_HOOK ||
+ qp_password.tp == QP_HOOK)
+ {
+ return CPROTO_ERR_SERVICE_INVALID_REQUEST;
+ }
+
+ if (qp_port.via.int64 < 1 || qp_port.via.int64 > 65535)
+ {
+ sprintf(err_msg,
+ "invalid port number: %" PRId64
+ " (expecting a value between 0 and 65536)",
+ qp_port.via.int64);
+ return CPROTO_ERR_SERVICE;
+ }
+
+ port = (uint16_t) qp_port.via.int64;
+ uuid_generate(uuid);
+
+ CHECK_DBNAME_AND_CREATE_PATH
+
+ if (req == SERVICE_NEW_POOL)
+ {
+ sprintf(dbfn, "%s%s", dbpath, REINDEX_FN);
+ fp = fopen(dbfn, "w");
+ if (fp == NULL || fclose(fp))
+ {
+ siri_service_request_rollback(dbpath);
+ snprintf(
+ err_msg,
+ SIRI_MAX_SIZE_ERR_MSG,
+ "cannot open file for writing: %s",
+ dbfn);
+ return CPROTO_ERR_SERVICE;
+ }
+ }
+
+ if (siri_service_client_request(
+ pid,
+ port,
+ /* -1 = new pool */
+ (req == SERVICE_NEW_POOL) ? -1 : qp_pool.via.int64,
+ &uuid,
+ &qp_host,
+ &qp_username,
+ &qp_password,
+ &qp_dbname,
+ dbpath,
+ client,
+ err_msg))
+ {
+ siri_service_request_rollback(dbpath);
+ return CPROTO_ERR_SERVICE;
+ }
+ return CPROTO_DEFERRED;
+}
+
+/*
+ * Returns CPROTO_ACK_SERVICE_DATA when successful.
+ * In case of an error CPROTO_ERR_SERVICE will be returned and err_msg is set
+ */
+static cproto_server_t SERVICE_on_get_version(
+ qp_unpacker_t * qp_unpacker __attribute__((unused)),
+ qp_packer_t ** packaddr,
+ char * err_msg)
+{
+ qp_packer_t * packer = sirinet_packer_new(128);
+ if (packer != NULL)
+ {
+ if (!qp_add_type(packer, QP_ARRAY_OPEN) &&
+ !qp_add_string(packer, SIRIDB_VERSION))
+ {
+ *packaddr = packer;
+ return CPROTO_ACK_SERVICE_DATA;
+ }
+
+ /* error, free packer */
+ qp_packer_free(packer);
+ }
+ sprintf(err_msg, "memory allocation error");
+ return CPROTO_ERR_SERVICE;
+}
+
+static cproto_server_t SERVICE_on_get_accounts(
+ qp_unpacker_t * qp_unpacker __attribute__((unused)),
+ qp_packer_t ** packaddr,
+ char * err_msg)
+{
+ qp_packer_t * packer = sirinet_packer_new(128);
+
+ if (packer != NULL)
+ {
+ qp_add_type(packer, QP_ARRAY_OPEN);
+
+ if (!llist_walk(
+ siri.accounts,
+ (llist_cb) SERVICE_list_accounts,
+ packer))
+ {
+ *packaddr = packer;
+ return CPROTO_ACK_SERVICE_DATA;
+ }
+
+ /* error, free packer */
+ qp_packer_free(packer);
+ }
+ sprintf(err_msg, "memory allocation error");
+ return CPROTO_ERR_SERVICE;
+}
+
+static cproto_server_t SERVICE_on_get_databases(
+ qp_unpacker_t * qp_unpacker __attribute__((unused)),
+ qp_packer_t ** packaddr,
+ char * err_msg)
+{
+ qp_packer_t * packer = sirinet_packer_new(128);
+
+ if (packer != NULL)
+ {
+ qp_add_type(packer, QP_ARRAY_OPEN);
+
+ if (!llist_walk(
+ siri.siridb_list,
+ (llist_cb) SERVICE_list_databases,
+ packer))
+ {
+ *packaddr = packer;
+ return CPROTO_ACK_SERVICE_DATA;
+ }
+
+ /* error, free packer */
+ qp_packer_free(packer);
+ }
+ sprintf(err_msg, "memory allocation error");
+ return CPROTO_ERR_SERVICE;
+}
+
+void siri_service_request_rollback(const char * dbpath)
+{
+ size_t dbpath_len = strlen(dbpath);
+ char dbfn[dbpath_len + max_filename_sz];
+
+ sprintf(dbfn, "%s%s", dbpath, DB_CONF_FN);
+ unlink(dbfn);
+ sprintf(dbfn, "%s%s", dbpath, DB_DAT_FN);
+ unlink(dbfn);
+ sprintf(dbfn, "%s%s", dbpath, REINDEX_FN);
+ unlink(dbfn);
+ if (rmdir(dbpath))
+ {
+ log_error("Roll-back creating new database has failed.");
+ }
+}
+
+static int8_t SERVICE_time_precision(qp_obj_t * qp_time_precision)
+{
+ if (qp_time_precision->tp != QP_RAW)
+ {
+ return -1;
+ }
+ if (qp_time_precision->len == 1 && qp_time_precision->via.raw[0] == 's')
+ {
+ return 0;
+ }
+ else if (qp_time_precision->len == 2 && qp_time_precision->via.raw[1] == 's')
+ {
+ switch (qp_time_precision->via.raw[0])
+ {
+ case 'm': return 1;
+ case 'u': return 2;
+ case 'n': return 3;
+ }
+ }
+ return -1;
+}
+
+static int64_t SERVICE_duration(qp_obj_t * qp_duration, uint8_t time_precision)
+{
+ char * endptr;
+ long int val;
+
+ if (qp_duration->tp != QP_RAW || qp_duration->len < 2)
+ {
+ return -1;
+ }
+
+ val = strtol((const char *) qp_duration->via.raw, &endptr, 10);
+
+ if (val < 1 || val > 99 || endptr == (const char *) qp_duration->via.raw)
+ {
+ return -1;
+ }
+
+ if (endptr != (const char *) qp_duration->via.raw + (qp_duration->len - 1))
+ {
+ return -1;
+ }
+
+ switch (*endptr)
+ {
+ case 'h': return xmath_ipow(1000, time_precision) * val * 3600;
+ case 'd': return xmath_ipow(1000, time_precision) * val * 86400;
+ case 'w': return xmath_ipow(1000, time_precision) * val * 604800;
+ }
+
+ return -1;
+}
+
+static int SERVICE_list_databases(siridb_t * siridb, qp_packer_t * packer)
+{
+ return qp_add_string(packer, siridb->dbname);
+}
+
+static int SERVICE_find_database(siridb_t * siridb, qp_obj_t * dbname)
+{
+ return (
+ strlen(siridb->dbname) == dbname->len &&
+ strncmp(
+ siridb->dbname,
+ (const char *) dbname->via.raw,
+ dbname->len) == 0);
+}
+
+static int SERVICE_list_accounts(
+ siri_service_account_t * account,
+ qp_packer_t * packer)
+{
+ return qp_add_string(packer, account->account);
+}
/*
- * siri.h - global methods for SiriDB.
+ * siri.c - Root for SiriDB.
*
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-03-2016
*
* Info siri->siridb_mutex:
*
#include <assert.h>
#include <logger/logger.h>
#include <qpack/qpack.h>
-#include <siri/admin/account.h>
-#include <siri/admin/request.h>
+#include <siri/service/account.h>
+#include <siri/service/request.h>
#include <siri/async.h>
#include <siri/buffersync.h>
#include <siri/cfg/cfg.h>
#include <siri/version.h>
#include <stddef.h>
#include <stdio.h>
-#include <strextra/strextra.h>
+#include <xstr/xstr.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
for (n = 0; n < LOGGER_NUM_LEVELS; n++)
{
strcpy(lname, LOGGER_LEVEL_NAMES[n]);
- strx_lower_case(lname);
+ xstr_lower_case(lname);
if (strlen(lname) == len && strcmp(siri.args->log_level, lname) == 0)
{
logger_init(stdout, n);
uv_loop_init(siri.loop);
/* initialize the back-end-, client- server and load databases */
- if ( (rc = siri_admin_account_init(&siri)) ||
- (rc = siri_admin_request_init()) ||
+ if ( (rc = siri_service_account_init(&siri)) ||
+ (rc = siri_service_request_init()) ||
(rc = sirinet_bserver_init(&siri)) ||
(rc = sirinet_clserver_init(&siri)) ||
(rc = SIRI_load_databases()))
/* free siridb grammar */
cleri_grammar_free(siri.grammar);
- /* free siridb administrative accounts */
- siri_admin_account_destroy(&siri);
+ /* free siridb service accounts */
+ siri_service_account_destroy(&siri);
- /* free siridb admin request */
- siri_admin_request_destroy();
+ /* free siridb service request */
+ siri_service_request_destroy();
/* free config */
siri_cfg_destroy(&siri);
/*
- * version.c - contains SiriDB version info.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 08-03-2016
- *
+ * version.c - SiriDB version info.
*/
#include <assert.h>
#include <siri/version.h>
+++ /dev/null
-/*
- * slist.c - Simple List
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 06-06-2016
- *
- */
-#include <logger/logger.h>
-#include <slist/slist.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define SLIST_MAX_SZ 512
-
-/*
- * Returns NULL in case an error has occurred.
- *
- * In case the size is unknown, SLIST_DEFAULT_SIZE is recommended since in this
- * case we can do a re-allocation with multiples of 64K.
- */
-slist_t * slist_new(size_t size)
-{
- /* sizeof(slist_t) is 16 bytes, only for len and size and data[] is
- * excluded.
- */
- slist_t * slist = (slist_t *)
- malloc(sizeof(slist_t) + sizeof(void *) * size);
-
- if (slist == NULL)
- {
- return NULL;
- }
- slist->size = size;
- slist->len = 0;
- return slist;
-}
-
-/*
- * Returns NULL in case an error has occurred.
- */
-slist_t * slist_copy(slist_t * source)
-{
- size_t size = sizeof(slist_t) + sizeof(void *) * source->size;
- slist_t * slist = (slist_t *) malloc(size);
- if (slist == NULL)
- {
- return NULL;
- }
- memcpy(slist, source, size);
- return slist;
-}
-
-/*
- * Returns 0 if successful or -1 in case of an error.
- * (in case of an error the list is unchanged)
- */
-int slist_append_safe(slist_t ** slist, void * data)
-{
- if ((*slist)->len == (*slist)->size)
- {
- slist_t * tmp;
-
- size_t sz = (*slist)->size;
-
- /* double the size when > 0 and < SLIST_MAX_SZ */
- (*slist)->size = (sz >= SLIST_DEFAULT_SIZE) ?
- (sz <= SLIST_MAX_SZ) ?
- sz * 2 : sz + SLIST_MAX_SZ : SLIST_DEFAULT_SIZE;
-
- tmp = (slist_t *) realloc(
- *slist,
- sizeof(slist_t) + sizeof(void *) * (*slist)->size);
-
- if (tmp == NULL)
- {
- /* an error has occurred */
- (*slist)->size = sz;
- return -1;
- }
-
- /* overwrite the original value with the new one */
- *slist = tmp;
- }
-
- slist_append((*slist), data);
-
- return 0;
-}
-
-/*
- * Compact memory used for the slist object when the list has more than
- * SLIST_DEFAULT_SIZE free space. After the compact the list has
- * a size which is SLIST_DEFAULT_SIZE greater than its length.
- */
-void slist_compact(slist_t ** slist)
-{
- size_t sz = (*slist)->size;
-
- if (sz - (*slist)->len > SLIST_DEFAULT_SIZE)
- {
- slist_t * tmp;
-
- (*slist)->size = (*slist)->len + SLIST_DEFAULT_SIZE;
-
- tmp = (slist_t *) realloc(
- *slist,
- sizeof(slist_t) + sizeof(void *) * (*slist)->size);
-
- if (tmp == NULL)
- {
- /* an error has occurred; log and restore size */
- log_error("Error has occurred while re-allocating less space");
- (*slist)->size = sz;
- }
- else
- {
- /* overwrite the original value with the new one */
- *slist = tmp;
- }
- }
-}
+++ /dev/null
-/*
- * strextra.c - Extra String functions used by SiriDB
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 19-03-2016
- *
- */
-#include <ctype.h>
-#include <inttypes.h>
-#include <logger/logger.h>
-#include <math.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-void strx_lower_case(char * sptr)
-{
- for (; *sptr != '\0'; sptr++)
- *sptr = tolower( (unsigned char) * sptr);
-}
-
-void strx_upper_case(char * sptr)
-{
- for (; *sptr != '\0'; sptr++)
- *sptr = toupper( (unsigned char) * sptr);
-}
-
-void strx_replace_char(char * sptr, char orig, char repl)
-{
- for (; *sptr != '\0'; sptr++)
- {
- if (*sptr == orig)
- {
- *sptr = repl;
- }
- }
-}
-
-/*
- * Replace all occurrences of 'o' with 'r' in 'str'. We restrict the new size
- * to 'n'.
- *
- * Returns 0 if successful or -1 if the replaced string does not fit. In this
- * case the original string is untouched. The new string is terminated.
- */
-int strx_replace_str(char * str, char * o, char * r, size_t n)
-{
- char buffer[n];
- char * pos, * s;
- size_t l, size = 0, olen = strlen(o), rlen = strlen(r);
-
- for (s = str; (pos = strstr(s, o)) != NULL; s = pos + olen)
- {
- l = pos - s;
-
- if (size + l + rlen >= n)
- {
- return -1;
- }
-
- memcpy(buffer + size, s, l);
- size += l;
-
- memcpy(buffer + size, r, rlen);
- size += rlen;
-
- }
-
- if (s != str)
- {
- memcpy(str, buffer, size);
- str[size] = '\0';
- }
-
- return 0;
-}
-
-/*
- * Split and then join a given string.
- *
- * For example:
- * string: " this is a test "
- * split: ' ' and join with '_'
- * result: "this_is_a_test"
- */
-void strx_split_join(char * pt, char split_chr, char join_chr)
-{
- int join = -1;
- char * dest = pt;
-
- for (; *pt != '\0'; pt++)
- {
- if (*pt != split_chr)
- {
- if (join > 0)
- {
- *dest = join_chr;
- dest++;
- }
- join = 0;
- *dest = *pt;
- dest++;
- }
- else if (!join)
- {
- join = 1;
- }
- }
-
- *dest = '\0';
-}
-
-void strx_trim(char ** str, char chr)
-{
- /*
- * trim: when chr is 0 we will trim whitespace,
- * otherwise only the given char.
- */
- char * end;
-
- /* trim leading chars */
- while ((chr && **str == chr) || (!chr && isspace(**str)))
- {
- (*str)++;
- }
-
- /* check all chars? */
- if(**str == 0)
- {
- return;
- }
-
- /* trim trailing chars */
- end = *str + strlen(*str) - 1;
- while (end > *str &&
- ((chr && *end == chr) || (!chr && isspace(*end))))
- {
- end--;
- }
-
- /* write new null terminator */
- *(end + 1) = 0;
-}
-
-/*
- * returns true or false
- */
-bool strx_is_empty(const char * str)
-{
- const char * test = str;
- for (; *test; test++)
- {
- if (!isspace(*test))
- {
- return false;
- }
- }
- return true;
-}
-
-bool strx_is_int(const char * str)
-{
- /* Handle negative numbers. */
- if (*str == '-')
- {
- ++str;
- }
-
- /* Handle empty string or just "-". */
- if (!*str)
- {
- return false;
- }
-
- /* Check for non-digit chars in the rest of the string. */
- while (*str)
- {
- if (!isdigit(*str))
- {
- return false;
- }
- else
- {
- ++str;
- }
- }
-
- return true;
-}
-
-bool strx_is_float(const char * str)
-{
- /* Handle negative numbers. */
- if (*str == '-' || *str == '+')
- {
- ++str;
- }
-
- size_t dots = 0;
-
- /* Handle empty string or just "-". */
- if (!*str)
- {
- return false;
- }
-
- /* Check for non-digit chars in the rest of the string. */
- while (*str)
- {
- if (*str == '.')
- {
- ++dots;
- }
- else if (!isdigit(*str))
- {
- return false;
- }
-
- ++str;
- }
-
- return dots == 1;
-}
-
-bool strx_is_graph(const char * str)
-{
- for (; *str; str++)
- {
- if (!isgraph(*str))
- {
- return false;
- }
- }
- return true;
-}
-
-/*
- * This function is used to extra a SiriDB string. These strings start
- * with " or with ' and we should replace double this character in the
- * string with a single one.
- *
- * 'dest' string will be terminated and the return value is the new
- * length of 'dest'.
- */
-size_t strx_extract_string(char * dest, const char * source, size_t len)
-{
- size_t i = 0;
-
- /* take the first character, this is " or ' */
- char chr = *source;
-
- /* we need to loop till len-2 so take 2 */
- for (len -= 2; i < len; i++)
- {
- source++;
- if (*source == chr)
- {
- /* this is the character, skip one and take the next */
- source++;
- len--;
- }
- dest[i] = *source;
- }
-
- /* set final 0 */
- dest[i] = 0;
-
- return i;
-}
-
-/*
- * Returns a string to double.
- * No error checking is done, we make the following assumptions:
- * - len > 0
- * - string is allowed to have one dot (.) at most but not required
- * - string can start with a plus (+) or minus (-) sign.
- */
-double strx_to_double(const char * src, size_t len)
-{
- char * pt = (char *) src;
- double d = 0;
- double convert;
-
- switch (*pt)
- {
- case '-':
- convert = -1.0;
- pt++;
- break;
- case '+':
- pt++;
- /* FALLTHRU */
- /* no break */
- default:
- convert = 1.0;
- }
-
- uint64_t r1 = *pt - '0';
-
- while (--len && isdigit(*(++pt)))
- {
- r1 = 10 * r1 + *pt - '0';
- }
-
- d = (double) r1;
-
- if (--len && *(pt++) == '.')
- {
- uint64_t r2 = *pt - '0';
- ssize_t i;
- for (i = -1; --len && isdigit(*(++pt)); i--)
- {
- r2 = 10 * r2 + *pt - '0';
- }
-
- d += pow(10, i) * (double) r2;
- }
-
- return convert * d;
-}
-
-/*
- * Returns a string to uint64_t.
- * No error checking is done, we make the following assumptions:
- * - len > 0
- * - string can only contain characters [0..9] and no signs
- */
-uint64_t strx_to_uint64(const char * src, size_t len)
-{
- char * pt = (char *) src;
-
- uint64_t i = *pt - '0';
-
- while (--len && isdigit(*(++pt)))
- {
- i = 10 * i + *pt - '0';
- }
-
- return i;
-}
-
-/*
- * Returns a string duplicate like strdup() and set the strlen() to n;
- */
-char * strx_dup(const char * src, size_t * n)
-{
- *n = strlen(src);
- char * nstr = (char *) malloc(*n + 1);
- if (nstr)
- {
- memcpy(nstr, src, *n + 1);
- }
- return nstr;
-}
/*
* timeit.c - Timeit.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 16-03-2016
- *
*/
#include <timeit/timeit.h>
#include <time.h>
--- /dev/null
+/*
+ * vec.c - Vector List.
+ */
+#include <logger/logger.h>
+#include <vec/vec.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define VEC_MAX_SZ 512
+
+/*
+ * Returns NULL in case an error has occurred.
+ *
+ * In case the size is unknown, VEC_DEFAULT_SIZE is recommended since in this
+ * case we can do a re-allocation with multiples of 64K.
+ */
+vec_t * vec_new(size_t size)
+{
+ /* sizeof(vec_t) is 16 bytes, only for len and size and data[] is
+ * excluded.
+ */
+ vec_t * vec = (vec_t *)
+ malloc(sizeof(vec_t) + sizeof(void *) * size);
+
+ if (vec == NULL)
+ {
+ return NULL;
+ }
+ vec->size = size;
+ vec->len = 0;
+ return vec;
+}
+
+/*
+ * Returns NULL in case an error has occurred.
+ */
+vec_t * vec_copy(vec_t * source)
+{
+ size_t size = sizeof(vec_t) + sizeof(void *) * source->size;
+ vec_t * vec = (vec_t *) malloc(size);
+ if (vec == NULL)
+ {
+ return NULL;
+ }
+ memcpy(vec, source, size);
+ return vec;
+}
+
+/*
+ * Returns 0 if successful or -1 in case of an error.
+ * (in case of an error the list is unchanged)
+ */
+int vec_append_safe(vec_t ** vec, void * data)
+{
+ if ((*vec)->len == (*vec)->size)
+ {
+ vec_t * tmp;
+
+ size_t sz = (*vec)->size;
+
+ /* double the size when > 0 and < VEC_MAX_SZ */
+ (*vec)->size = (sz >= VEC_DEFAULT_SIZE) ?
+ (sz <= VEC_MAX_SZ) ?
+ sz * 2 : sz + VEC_MAX_SZ : VEC_DEFAULT_SIZE;
+
+ tmp = (vec_t *) realloc(
+ *vec,
+ sizeof(vec_t) + sizeof(void *) * (*vec)->size);
+
+ if (tmp == NULL)
+ {
+ /* an error has occurred */
+ (*vec)->size = sz;
+ return -1;
+ }
+
+ /* overwrite the original value with the new one */
+ *vec = tmp;
+ }
+
+ vec_append((*vec), data);
+
+ return 0;
+}
+
+/*
+ * Compact memory used for the vec object when the list has more than
+ * VEC_DEFAULT_SIZE free space. After the compact the list has
+ * a size which is VEC_DEFAULT_SIZE greater than its length.
+ */
+void vec_compact(vec_t ** vec)
+{
+ size_t sz = (*vec)->size;
+
+ if (sz - (*vec)->len > VEC_DEFAULT_SIZE)
+ {
+ vec_t * tmp;
+
+ (*vec)->size = (*vec)->len + VEC_DEFAULT_SIZE;
+
+ tmp = (vec_t *) realloc(
+ *vec,
+ sizeof(vec_t) + sizeof(void *) * (*vec)->size);
+
+ if (tmp == NULL)
+ {
+ /* an error has occurred; log and restore size */
+ log_error("Error has occurred while re-allocating less space");
+ (*vec)->size = sz;
+ }
+ else
+ {
+ /* overwrite the original value with the new one */
+ *vec = tmp;
+ }
+ }
+}
/*
- * xmath.c - Extra math functions which are useful.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 12-03-2016
- *
+ * xmath.c - Extra math functions functions used by SiriDB.
*/
#include <xmath/xmath.h>
#include <stdarg.h>
/*
- * xpath.c - Path and file tools
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 15-07-2016
- *
+ * xpath.c - Path and file tools.
*/
#include <limits.h>
#include <logger/logger.h>
--- /dev/null
+/*
+ * xstr.c - Extra String functions used by SiriDB.
+ */
+#include <ctype.h>
+#include <inttypes.h>
+#include <logger/logger.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void xstr_lower_case(char * sptr)
+{
+ for (; *sptr != '\0'; sptr++)
+ *sptr = tolower( (unsigned char) * sptr);
+}
+
+void xstr_upper_case(char * sptr)
+{
+ for (; *sptr != '\0'; sptr++)
+ *sptr = toupper( (unsigned char) * sptr);
+}
+
+void xstr_replace_char(char * sptr, char orig, char repl)
+{
+ for (; *sptr != '\0'; sptr++)
+ {
+ if (*sptr == orig)
+ {
+ *sptr = repl;
+ }
+ }
+}
+
+/*
+ * Replace all occurrences of 'o' with 'r' in 'str'. We restrict the new size
+ * to 'n'.
+ *
+ * Returns 0 if successful or -1 if the replaced string does not fit. In this
+ * case the original string is untouched. The new string is terminated.
+ */
+int xstr_replace_str(char * str, char * o, char * r, size_t n)
+{
+ char buffer[n];
+ char * pos, * s;
+ size_t l, size = 0, olen = strlen(o), rlen = strlen(r);
+
+ for (s = str; (pos = strstr(s, o)) != NULL; s = pos + olen)
+ {
+ l = pos - s;
+
+ if (size + l + rlen >= n)
+ {
+ return -1;
+ }
+
+ memcpy(buffer + size, s, l);
+ size += l;
+
+ memcpy(buffer + size, r, rlen);
+ size += rlen;
+
+ }
+
+ if (s != str)
+ {
+ memcpy(str, buffer, size);
+ str[size] = '\0';
+ }
+
+ return 0;
+}
+
+/*
+ * Split and then join a given string.
+ *
+ * For example:
+ * string: " this is a test "
+ * split: ' ' and join with '_'
+ * result: "this_is_a_test"
+ */
+void xstr_split_join(char * pt, char split_chr, char join_chr)
+{
+ int join = -1;
+ char * dest = pt;
+
+ for (; *pt != '\0'; pt++)
+ {
+ if (*pt != split_chr)
+ {
+ if (join > 0)
+ {
+ *dest = join_chr;
+ dest++;
+ }
+ join = 0;
+ *dest = *pt;
+ dest++;
+ }
+ else if (!join)
+ {
+ join = 1;
+ }
+ }
+
+ *dest = '\0';
+}
+
+void xstr_trim(char ** str, char chr)
+{
+ /*
+ * trim: when chr is 0 we will trim whitespace,
+ * otherwise only the given char.
+ */
+ char * end;
+
+ /* trim leading chars */
+ while ((chr && **str == chr) || (!chr && isspace(**str)))
+ {
+ (*str)++;
+ }
+
+ /* check all chars? */
+ if(**str == 0)
+ {
+ return;
+ }
+
+ /* trim trailing chars */
+ end = *str + strlen(*str) - 1;
+ while (end > *str &&
+ ((chr && *end == chr) || (!chr && isspace(*end))))
+ {
+ end--;
+ }
+
+ /* write new null terminator */
+ *(end + 1) = 0;
+}
+
+/*
+ * returns true or false
+ */
+bool xstr_is_empty(const char * str)
+{
+ const char * test = str;
+ for (; *test; test++)
+ {
+ if (!isspace(*test))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool xstr_is_int(const char * str)
+{
+ /* Handle negative numbers. */
+ if (*str == '-')
+ {
+ ++str;
+ }
+
+ /* Handle empty string or just "-". */
+ if (!*str)
+ {
+ return false;
+ }
+
+ /* Check for non-digit chars in the rest of the string. */
+ while (*str)
+ {
+ if (!isdigit(*str))
+ {
+ return false;
+ }
+ else
+ {
+ ++str;
+ }
+ }
+
+ return true;
+}
+
+bool xstr_is_float(const char * str)
+{
+ /* Handle negative numbers. */
+ if (*str == '-' || *str == '+')
+ {
+ ++str;
+ }
+
+ size_t dots = 0;
+
+ /* Handle empty string or just "-". */
+ if (!*str)
+ {
+ return false;
+ }
+
+ /* Check for non-digit chars in the rest of the string. */
+ while (*str)
+ {
+ if (*str == '.')
+ {
+ ++dots;
+ }
+ else if (!isdigit(*str))
+ {
+ return false;
+ }
+
+ ++str;
+ }
+
+ return dots == 1;
+}
+
+bool xstr_is_graph(const char * str)
+{
+ for (; *str; str++)
+ {
+ if (!isgraph(*str))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+/*
+ * This function is used to extra a SiriDB string. These strings start
+ * with " or with ' and we should replace double this character in the
+ * string with a single one.
+ *
+ * 'dest' string will be terminated and the return value is the new
+ * length of 'dest'.
+ */
+size_t xstr_extract_string(char * dest, const char * source, size_t len)
+{
+ size_t i = 0;
+
+ /* take the first character, this is " or ' */
+ char chr = *source;
+
+ /* we need to loop till len-2 so take 2 */
+ for (len -= 2; i < len; i++)
+ {
+ source++;
+ if (*source == chr)
+ {
+ /* this is the character, skip one and take the next */
+ source++;
+ len--;
+ }
+ dest[i] = *source;
+ }
+
+ /* set final 0 */
+ dest[i] = 0;
+
+ return i;
+}
+
+/*
+ * Returns a string to double.
+ * No error checking is done, we make the following assumptions:
+ * - len > 0
+ * - string is allowed to have one dot (.) at most but not required
+ * - string can start with a plus (+) or minus (-) sign.
+ */
+double xstr_to_double(const char * src, size_t len)
+{
+ char * pt = (char *) src;
+ double d = 0;
+ double convert;
+
+ switch (*pt)
+ {
+ case '-':
+ convert = -1.0;
+ pt++;
+ break;
+ case '+':
+ pt++;
+ /* FALLTHRU */
+ /* no break */
+ default:
+ convert = 1.0;
+ }
+
+ uint64_t r1 = *pt - '0';
+
+ while (--len && isdigit(*(++pt)))
+ {
+ r1 = 10 * r1 + *pt - '0';
+ }
+
+ d = (double) r1;
+
+ if (--len && *(pt++) == '.')
+ {
+ uint64_t r2 = *pt - '0';
+ ssize_t i;
+ for (i = -1; --len && isdigit(*(++pt)); i--)
+ {
+ r2 = 10 * r2 + *pt - '0';
+ }
+
+ d += pow(10, i) * (double) r2;
+ }
+
+ return convert * d;
+}
+
+/*
+ * Returns a string to uint64_t.
+ * No error checking is done, we make the following assumptions:
+ * - len > 0
+ * - string can only contain characters [0..9] and no signs
+ */
+uint64_t xstr_to_uint64(const char * src, size_t len)
+{
+ char * pt = (char *) src;
+
+ uint64_t i = *pt - '0';
+
+ while (--len && isdigit(*(++pt)))
+ {
+ i = 10 * i + *pt - '0';
+ }
+
+ return i;
+}
+
+/*
+ * Returns a string duplicate like strdup() and set the strlen() to n;
+ */
+char * xstr_dup(const char * src, size_t * n)
+{
+ *n = strlen(src);
+ char * nstr = (char *) malloc(*n + 1);
+ if (nstr)
+ {
+ memcpy(nstr, src, *n + 1);
+ }
+ return nstr;
+}
../src/siri/db/re.c
../src/siri/err.c
../src/qpack/qpack.c
-../src/slist/slist.c
+../src/vec/vec.c
../src/cexpr/cexpr.c
-../src/strextra/strextra.c
+../src/xstr/xstr.c
../src/logger/logger.c
../src/imap/imap.c
-../src/slist/slist.c
+../src/vec/vec.c
../src/logger/logger.c
\ No newline at end of file
static int test__imap_decref_cb(char * series)
{
- ((slist_object_t *) series)->ref--;
+ ((vec_object_t *) series)->ref--;
return 1;
}
-../src/slist/slist.c
+../src/vec/vec.c
../src/ctree/ctree.c
../src/xpath/xpath.c
../src/xmath/xmath.c
../src/imap/imap.c
../src/llist/llist.c
../src/logger/logger.c
-../src/strextra/strextra.c
+../src/xstr/xstr.c
../src/cfgparser/cfgparser.c
../src/owcrypt/owcrypt.c
../src/cexpr/cexpr.c
../src/siri/db/walker.c
../src/siri/file/handler.c
../src/siri/file/pointer.c
-../src/siri/admin/account.c
-../src/siri/admin/client.c
-../src/siri/admin/request.c
+../src/siri/service/account.c
+../src/siri/service/client.c
+../src/siri/service/request.c
../src/siri/help/help.c
../src/siri/cfg/cfg.c
../src/siri/grammar/grammar.c
\ No newline at end of file
-../src/slist/slist.c
+../src/vec/vec.c
../src/logger/logger.c
\ No newline at end of file
#include "../test.h"
-#include <slist/slist.h>
+#include <vec/vec.h>
const unsigned int num_entries = 14;
char * entries[] = {
int main()
{
- test_start("slist");
+ test_start("vec");
- /* slist_append_safe */
+ /* vec_append_safe */
{
- slist_t * slist = slist_new(0);
- _assert (slist->len == 0);
- _assert (slist->size == 0);
+ vec_t * vec = vec_new(0);
+ _assert (vec->len == 0);
+ _assert (vec->size == 0);
unsigned int i;
for (i = 0; i < num_entries; i++)
{
- _assert (slist_append_safe(&slist, entries[i]) == 0);
+ _assert (vec_append_safe(&vec, entries[i]) == 0);
}
- /* slist_copy */
+ /* vec_copy */
{
- slist_t * slistcp = slist_copy(slist);
+ vec_t * veccp = vec_copy(vec);
unsigned int i;
for (i = 0; i < num_entries; i++)
{
- _assert (slistcp->data[i] == entries[i]);
+ _assert (veccp->data[i] == entries[i]);
}
- slist_free(slistcp);
+ vec_free(veccp);
}
- _assert (slist->len == num_entries);
- slist_free(slist);
+ _assert (vec->len == num_entries);
+ vec_free(vec);
}
- /* slist_append */
+ /* vec_append */
{
- slist_t * slist = slist_new(num_entries);
- _assert (slist->len == 0);
- _assert (slist->size == num_entries);
+ vec_t * vec = vec_new(num_entries);
+ _assert (vec->len == 0);
+ _assert (vec->size == num_entries);
unsigned int i;
for (i = 0; i < num_entries; i++)
{
- slist_append(slist, entries[i]);
+ vec_append(vec, entries[i]);
}
- _assert (slist->len == num_entries);
+ _assert (vec->len == num_entries);
- /* slist_pop */
+ /* vec_pop */
for (i = num_entries; i-- > 0;)
{
- _assert (slist_pop(slist) == entries[i]);
+ _assert (vec_pop(vec) == entries[i]);
}
- slist_free(slist);
+ vec_free(vec);
}
+++ /dev/null
-../src/strextra/strextra.c
+++ /dev/null
-#include "../test.h"
-#include <strextra/strextra.h>
-
-
-int main()
-{
- test_start("strx");
-
- /* strx_to_double */
- {
- _assert (strx_to_double("0.5", 3) == 0.5);
- _assert (strx_to_double("0.55", 3) == 0.5);
- _assert (strx_to_double("123.456", 7) == 123.456);
- _assert (strx_to_double("123", 3) == 123);
- _assert (strx_to_double("123.", 4) == 123);
- _assert (strx_to_double("123456.", 3) == 123);
- _assert (strx_to_double("-0.5", 3) == -0.5);
- }
-
- return test_end();
-}
--- /dev/null
+../src/xstr/xstr.c
--- /dev/null
+#include "../test.h"
+#include <xstr/xstr.h>
+
+
+int main()
+{
+ test_start("xstr");
+
+ /* xstr_to_double */
+ {
+ _assert (xstr_to_double("0.5", 3) == 0.5);
+ _assert (xstr_to_double("0.55", 3) == 0.5);
+ _assert (xstr_to_double("123.456", 7) == 123.456);
+ _assert (xstr_to_double("123", 3) == 123);
+ _assert (xstr_to_double("123.", 4) == 123);
+ _assert (xstr_to_double("123456.", 3) == 123);
+ _assert (xstr_to_double("-0.5", 3) == -0.5);
+ }
+
+ return test_end();
+}